在Python V.2.5.4中,我有一个浮点数,我想获取并操作(作为整数)浮点数的位模式。
例如,假设我有
x = 173.3125
在IEEE 754格式中,x的位模式(十六进制)为432D5000
。
我如何获得&对该位模式进行操作(例如,执行按位操作)?
答案 0 :(得分:13)
你可以使用struct
模块获得你想要的字符串(显然暗示一个大端,32位表示; Python内部使用本机字节序和64位浮点数):
>>> import struct
>>> x = 173.125
>>> s = struct.pack('>f', x)
>>> ''.join('%2.2x' % ord(c) for c in s)
'432d2000'
这还不允许你执行按位操作,但是你可以再次使用struct将字符串映射到int:
>>> i = struct.unpack('>l', s)[0]
>>> print hex(i)
0x432d2000
现在你有一个int
可以在任何类型的按位操作中使用(如果在所述操作之后需要再次获得float
,则按照相反的两个步骤进行操作)。
答案 1 :(得分:10)
问题是Python浮点对象可能不是IEEE 754,因为它是一个对象(实际上它们是,但在内部它们可以容纳任何表示更方便)...
正如leo所说,您可以使用ctypes进行类型转换,因此您要强制执行特定的表示(在本例中为单精度):
from ctypes import *
x = 173.3125
bits = cast(pointer(c_float(x)), POINTER(c_int32)).contents.value
print hex(bits)
#swap the least significant bit
bits ^= 1
然后回来:
y = cast(pointer(c_int32(bits)), POINTER(c_float)).contents.value
答案 2 :(得分:2)
使用struct
或xdrlib
模块:
>>> import struct
>>> x = 173.3125
>>> rep = struct.pack('>f', x)
>>> numeric = struct.unpack('>I', rep)[0]
>>> '%x' %numeric
'432d5000'
现在您可以使用numeric
,然后按相反的方向返回浮点数。你必须使用> I(unsigned int)来避免得到负数。 xdrlib
类似。
答案 3 :(得分:1)
作为参考,也可以使用numpy和view。
import numpy
def fextract( f ):
bits = numpy.asarray( f, dtype=numpy.float64 ).view( numpy.int64 )
if not bits & 0x7fffffffffffffff: # f == +/-0
return 0, 0
sign = numpy.sign(bits)
exponent = ( (bits>>52) & 0x7ff ) - 1075
mantissa = 0x10000000000000 | ( bits & 0xfffffffffffff )
# from here on f == sign * mantissa * 2**exponent
for shift in 32, 16, 8, 4, 2, 1:
if not mantissa & ((1<<shift)-1):
mantissa >>= shift
exponent += shift
return sign * mantissa, exponent
fextract( 1.5 ) # --> 3, -1
答案 4 :(得分:0)
我对这个主题并不太熟悉,但您是否尝试过ctypes
模块?