我正在尝试通过选择分数 位来创建浮点 NaN。但似乎 python float 在解释 NaN 时总是设置第 23 个小数位(IEEE754 单)。
所以,我的问题是:是否可以在不设置第 23 位的情况下在 python 中定义 float nan?
(我使用的是 Python 2.7)
NaNs in IEEE 754 have this format:
sign = either 0 or 1.
biased exponent = all 1 bits.
fraction = anything except all 0 bits (since all 0 bits represents infinity).
因此,NaN 的十六进制表示可能是 0x7F800001,但是当将此 int 解释为 float 并将其解释回 int 时,会得到 0x7FC00001
第一次尝试:struct.pack/unpack:
import struct
def hex_to_float(value):
return struct.unpack( '@f', struct.pack( '@L', value) )[0]
def float_to_hex(value):
return struct.unpack( '@L', struct.pack( '@f', value) )[0]
print hex(float_to_hex(hex_to_float(0x7f800001)))
# 0x7fc00001
第二次尝试:ctypes
import ctypes
def float2hex(float_input):
INTP = ctypes.POINTER(ctypes.c_uint)
float_value = ctypes.c_float(float_input)
my_pointer = ctypes.cast(ctypes.addressof(float_value), INTP)
return my_pointer.contents.value
def hex2float(hex_input):
FLOATP = ctypes.POINTER(ctypes.c_float)
int_value = ctypes.c_uint(hex_input)
my_pointer = ctypes.cast(ctypes.addressof(int_value), FLOATP)
return my_pointer.contents.value
print hex(float2hex(hex2float(0x7f800001)))
# 0x7fc00001L
第三次尝试:xdrlib packers。相同的结果。
最佳答案
潜在的问题是您将 C-float(具有 32 位)转换为 Python-float(具有 64 位,即 C 语言中的 double
),然后再转换回 C-float .
两个 cconversions 的执行并不总是导致原始输入 - 你正在目睹这种情况。
如果确切的位模式很重要,您应该不惜一切代价避免上述转换。
这里有一些血淋淋的细节:
所以当 struct.unpack('=f', some_bytes)
(请注意,与您使用的相比,我使用标准大小的 =
-format 字符 native 大小 ('@'),例如 @L
在 Windows 和 Linux 上表示不同的东西),会发生以下情况:
-
unpack_float
被调用,调用 -
_PyFloat_Unpack4
,它将数据( here 或 here )解释为 - 32bit-c-float , 即
float
, - 但将其转换为
double
(因为该函数返回一个“double”)while returning .
在 x86-64 上,最后一次转换意味着操作 VCVTSS2SD
(即将标量单精度浮点值转换为标量 double 浮点值)并且此操作导致
0x7f800001
变成 0x7ff8000020000000
。
如您所见,操作 struct.unpack( '=f', struct.pack( '=L', value) )[0]
的结果已经不是放入的结果.
但是,为 python-float value
(它是 C 的 double
), 将使我们到达 _PyFloat_Pack4
, where从 double
到 float
的转换发生了,即 CVTSD2SS
(Convert Scalar Double-Precision Floating-Point Value to Scalar Single-Precision Floating-Point Value) 被调用并且
0x7ff8000020000000
变为 0x7fc00001
。
关于python - 如何在不设置第 23 位的情况下在 python 中创建自定义 NaN(单精度)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56298877/