将16位整数转换为32位浮点数

4 投票
3 回答
11121 浏览
提问于 2025-04-16 23:26

我正在尝试把一段用另一种语言(叫做Igor Pro,是Wavemetrics公司开发的,可能很多人没听过)写的代码移植到Python中。

在这段代码中,有一个数据类型的转换,它是把从一个16位的大端二进制文件中读取的16位整数,转换成单精度(32位)浮点数。在这个程序中,转换的方式如下:

带符号的16位整数:

print tmp
tmp[0]={-24160,18597,-24160,18597,-24160}

转换成32位浮点数:

Redimension/S/E=1 tmp
print tmp
tmp[0]={339213,339213,5.79801e-41,0,0}

这里的/S选项表示tmp的数据类型应该是float32,而不是int16。不过,我认为更重要的选项是/E=1,它的意思是“强制重塑,而不转换或移动数据”。

在Python中,转换的方式如下:

>>> tmp[:5]
array([-24160,  18597, -24160,  18597, -24160], dtype=int16)

>>> tmp.astype('float32')
array([-24160.,  18597., -24160., ...,  18597., -24160.,  18597.], dtype=float32)

这是我所期待的结果,但我需要找到一个函数或操作,来模拟上面原始代码中的/E=1选项。有没有明显的方法可以把-24160和18597都转换成339213?这和byteswapnewbyteorder有关系吗,还是其他什么东西?

3 个回答

1

-24160和18597这两个数字有没有明显的方法可以都转换成339213呢?

没有,但也没有明显的方法可以让-24160同时转换成339213、5.79801e-41和0。

看起来这个转换是把两个输入数字结合起来,生成一个输出(可能是把两个16位的原始数字拼接成32位,然后把结果称为浮点数)。这样的话,组合成的数字对-24160,18597总是会变成339213,而5.79801e-41可能是由-24160,0产生的,0是因为我们没有更多的输入了。由于5.79801e-41看起来像是一个单精度的非标准数,这意味着这两个16位的块可能是以小端格式拼接在一起的。

接下来还需要看看是否需要对每个16位的输入进行字节交换,但这个你可以自己去检查。

2

使用 view 而不是 astype

In [9]: tmp=np.array([-24160,  18597, -24160,  18597, -24160, 18597], dtype=int16)

In [10]: tmp.view('float32')
Out[10]: array([ 339213.,  339213.,  339213.], dtype=float32)
  1. .astype 会创建一个新的数组,这个数组是按照新的数据类型来复制的。
  2. .view 则是返回一个数组的视图,它和原来的数据是共享的,只是用新的数据类型来解释这些数据。
6
import numpy
tmp=numpy.array([-24160,18597,-24160,18597,-24160, 0], numpy.int16)
tmp.dtype = numpy.float32
print tmp

结果:

[  3.39213000e+05   3.39213000e+05   5.79801253e-41]

我需要在数值列表中加一个零,因为数值的数量是奇数。由于有5个16位的数值,它无法把这些当作32位的浮点数来理解。

撰写回答