Python:获取&操纵(作为整数)浮点数的位模式

时间:2009-12-17 16:02:13

标签: python floating-point bit-manipulation

在Python V.2.5.4中,我有一个浮点数,我想获取并操作(作为整数)浮点数的位模式。

例如,假设我有

x = 173.3125

在IEEE 754格式中,x的位模式(十六进制)为432D5000

我如何获得&对该位模式进行操作(例如,执行按位操作)?

5 个答案:

答案 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)

使用structxdrlib模块:

>>> import struct
>>> x = 173.3125
>>> rep = struct.pack('>f', x)
>>> numeric = struct.unpack('>I', rep)[0]
>>> '%x' %numeric
'432d5000'

现在您可以使用numeric,然后按相反的方向返回浮点数。你必须使用> I(unsigned int)来避免得到负数。 xdrlib类似。

参考文献:structxdrlib

答案 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模块?