MATLAB将大端序字节转换为浮点数值

3

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

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 = [])。

1
如果您从文件中获取这些字节,可以使用freadfopen以正确的选项读取数据,从一开始就将其作为正确的浮点数读取。 如果这些字节来自别处-可能不适用... - sebastian
我本来也想加上这一点,看完下面@horchler的答案后,我记起从32位UV相机导入视频时,我使用了低级IO函数fread,精度设置为'uint32=>double',机器格式为'ieee-be' - Mark Mikofski
2个回答

4
优秀的示例在这里:链接
>> 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
1
@JDS:或者只需使用typecast(uint8(data(4:-1:1)),'single')。我相信您已经意识到最大的四字节uint32realmax('single')还要大?换句话说,任何大于[255 255 127 127]的值都会溢出并导致NaN - horchler

2

如果有用的话,我会把这个留在这里。正如@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本地的浮点数。


这适用于字节序的通用性吗? - JDS
@JDS:您是在问它是否处理转换大端或小端数据吗?这将把代表32位无符号整数(四个8位无符号整数)的四个字节组转换为双精度浮点数。它假设双精度浮点数已经编码(也就是返回的数据类型),并且输入数据的字节顺序是大端字节序。如果在任意一组四个字节上运行,它仍然可以工作,但可能会返回垃圾值。要想通用或者"双端",函数需要告诉数据的字节序。 - horchler
@JDS:顺便说一下,如果你正在使用freadfwrite读写文件,可以考虑使用这些函数或通过fopen指定的machineformat选项。这允许你告诉这些函数字节顺序。 - horchler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接