在Python V.2.5.4中,我有一個浮點數,我想獲取和操作(作爲整數)該浮點數的位模式。Python:獲取和操作(作爲整數)位浮點模式
例如,假設我有
x = 173.3125
在IEEE 754格式中,x的位模式(十六進制)是432D5000
。
如何獲得&對該位模式進行操作(例如,執行按位操作)?
在Python V.2.5.4中,我有一個浮點數,我想獲取和操作(作爲整數)該浮點數的位模式。Python:獲取和操作(作爲整數)位浮點模式
例如,假設我有
x = 173.3125
在IEEE 754格式中,x的位模式(十六進制)是432D5000
。
如何獲得&對該位模式進行操作(例如,執行按位操作)?
你可以得到你想要的字符串(顯然意味着一個大端,32位的表示; Python的內部使用本地endianity和浮動64位)與struct
模塊:
>>> import struct
>>> x = 173.125
>>> s = struct.pack('>f', x)
>>> ''.join('%2.2x' % ord(c) for c in s)
'432d2000'
這並沒有讓您執行位操作,但你就可以使用結構再次將字符串映射到一個int :
>>> i = struct.unpack('>l', s)[0]
>>> print hex(i)
0x432d2000
,現在你有一個int
,你可以在任何類型的按位運算的使用(請以相反兩個相同的步驟,如果說你需要獲得一個再次float
操作後)。
我對這個主題不太熟悉,但是您是否嘗試過ctypes
模塊?
的問題是一個Python浮動對象可能不是一個IEEE 754,因爲它是一個對象(事實上它們,但在內部,他們可以持有取其表示更方便)......
利奧說,你可以做一個類型轉換與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
作爲參考,它也可以使用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
感謝所有提供答案的人。我能夠獲得這兩種技術(1使用ctypes和2使用結構)工作。我不知道的是哪個是可取的。看來,使用pack&unpack結構提供了一種獨立於表示形式的解決方案,但如果我錯了,請糾正我。 – JaysonFix 2009-12-17 16:23:54
另外,我想知道「ctypes」和「struct」解決方案之間是否存在顯着的性能差異。 – JaysonFix 2009-12-17 16:25:43
@JaysonFix:1)你的意思是平臺無關嗎?如果是這樣,並且你明確地討論了endianism,我認爲答案是肯定的。2)對你而言是否有足夠的差異取決於你將要做什麼......數百萬次的操縱?如果是這樣,你應該爲自己設定基準,以便從易用性和可維護性兩個方面來理解它們的含義。 – 2009-12-17 18:04:30