Skip to main content
 首页 » 编程设计

python 32位 float 转换

2025年05月04日15小虾米

Redhat 6.3 上的 Python 2.6

我有一个设备可以在 2 个内存寄存器中保存 32 位浮点值,分为最高有效字和最低有效字。 我需要将其转换为 float 。 我一直在使用在 SO 上找到的以下代码,它类似于我在其他地方看到的代码

#!/usr/bin/env python 
import sys 
from ctypes import * 
first  = sys.argv[1] 
second = sys.argv[2] 
 
reading_1 = str(hex(int(first)).lstrip("0x")) 
reading_2 = str(hex(int(second)).lstrip("0x")) 
 
sample = reading_1 + reading_2 
 
def convert(s): 
    i = int(s, 16)                   # convert from hex to a Python int 
    cp = pointer(c_int(i))           # make this into a c integer 
    fp = cast(cp, POINTER(c_float))  # cast the int pointer to a float pointer 
    return fp.contents.value         # dereference the pointer, get the float 
 
print convert(sample) 

寄存器值的一个例子是;

寄存器 1;16282 寄存器 2;60597

这会产生

的 float

1.21034872532

一个完美的 cromulent 数字,但有时内存值是这样的;

寄存器 1;16282 寄存器 2;1147

其中,使用此函数会产生一个 float ;

1.46726675314e-36

这是一个非常小的数字,而不是一个看起来正确的数字。该设备应产生 1.2、1.3 范围内的读数。

我想弄清楚的是设备是否在抛出虚假值,或者我得到的值是否正确但我使用的函数无法正确转换它们。

还有没有更好的方法来做到这一点,比如使用 numpy 或类似的东西? 我会举起手来说,我只是从在线示例中复制了这段代码,我对它的工作原理知之甚少,但它似乎在我当时可用的测试用例中有效。

谢谢。

请您参考如下方法:

如果您有原始字节(例如,从内存、文件、网络读取...),您可以为此使用struct:

>>> import struct 
>>> struct.unpack('>f', '\x3f\x9a\xec\xb5')[0] 
1.2103487253189087 

此处,\x3f\x9a\xec\xb5 是您的输入寄存器,16282(十六进制 0x3f9a)和 60597(十六进制 0xecb5)表示为字符串中的字节。 > 是字节顺序标记。

因此,根据您获取寄存器值的方式,您可以使用此方法(例如,通过将输入整数转换为字节字符串)。您也可以为此使用 struct;这是你的第二个例子:

>>> raw = struct.pack('>HH', 16282, 1147)    # from two unsigned shorts 
>>> struct.unpack('>f', raw)[0]              # to one float 
1.2032617330551147