【问题标题】:MATLAB convert big-endian order bytes into floating point valuesMATLAB 将大端顺序字节转换为浮点值
【发布时间】:2013-12-30 08:44:11
【问题描述】:

我将以下字节存储在向量中:

data = [189    33   136   147]

这 4 个字节代表一个大端顺序的浮点数。如何在 MATLAB 中获得这个数字?

我需要连接和转换。我试过了:

x = typecast(str2num(sprintf('%d%d%d%d',data(1),data(2),data(3),data(4))), 'single')

无济于事(我得到了x = [])。

【问题讨论】:

  • 如果您从文件中获取这些字节,您可以使用freadfopen 和适当的选项从一开始就将数据读取为正确的浮点数。如果字节来自其他地方 - 这可能不适用......
  • 我正打算自己补充这一点,看了下面@horchler的answer后,我记得在从32位UV相机导入视频时,我使用了低级IO功能fread,精度设置为'uint32=>double',机器格式为'ieee-be'

标签: matlab floating-point byte endianness


【解决方案1】:

我会把它留在这里,以防它对任何人有用。正如@MarkMikofski 所示,使用typecastswapbytes 是标准方法。但是,如果您的数据已经是浮点数,则这些函数在某些情况下可能效率低下。我在我的视频编码/解码工具中使用了以下实用功能:

function x = Bit32toDouble(y)
n = numel(y);
if n >= 65536
    x = double(swapbytes(typecast(uint8(y(:)),'uint32'))).';
elseif n > 4
    x = sum(bsxfun(@times,[16777216;65536;256;1],reshape(y(:),4,n/4)));
else
    x = sum([16777216;65536;256;1].*y(:));
end

根据传入的字节数有不同的情况。只有在一次处理大量数据时,typecast/swapbytes效率最高。如果使用较小的输入重复调用该函数(这在我的应用程序中很常见),则其他情况会快得多,因为它们在 Matlab 的本机浮点中执行所有操作。

【讨论】:

  • 这对 Endian 顺序是通用的吗?
  • @JDS:您是在问是否会处理大端或小端数据的转换?这会将表示 32 位无符号整数(四个 8 位无符号整数)的四个字节组转换为双精度数。它假定双精度数已编码(即返回的 dat 类型),并且输入数据的字节按大端顺序排列。如果在任意四个字节的任意集合上运行,它仍然可以工作,但可能会返回垃圾。为了通用或"bi-endian,函数需要被告知数据的字节顺序。
  • @JDS: 顺便说一下,如果您使用freadfwrite 读取或写入文件,您可以查看可以在这些函数中指定的machineformat 选项或通过fopen。这允许您告诉这些函数字节顺序。
【解决方案2】:

很好的例子here:

>> dataL = typecast(uint8([189, 33, 136, 147]), 'uint32')
dataL =
   2475172285
>> dataF = double(dataL)
dataF =
   2.4752e+09

从大到小,试试swapbytes

>> dataLbig = swapbytes(dataL)
dataLbig =
   3173091475
>> dataFbig = double(dataLbig)
dataFbig =
   3.1731e+09

这是你所期待的吗?

【讨论】:

  • 这让我找到了解决方案。这是答案:x = typecast(uint8([data(4),data(3),data(2),data(1)]), 'single')
  • @JDS:或者只是typecast(uint8(data(4:-1:1)),'single')。我相信您知道最大的四个字节uint32 大于realmax('single')?换句话说,任何大于[255 255 127 127] 的东西都会溢出并导致NaN
猜你喜欢
  • 1970-01-01
  • 2011-02-16
  • 1970-01-01
  • 2010-09-05
  • 2013-01-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多