Python: 在浮动中翻转一点

Python: flip a bit in a float

我想翻转 Python 中浮点数中的特定位。 好像挺难的,因为操作数 |仅适用于整数。

现在我尝试将 float 转换为 int:Get the "bits" of a float in Python? 但是建议的解决方案似乎不适用于太大的浮动。

使用 struct.packstruct.unpack。这是在 Python 下测试的 3. Python 可能存在差异 2,请查阅文档。

>>> from struct import pack,unpack
>>> fs = pack('f',1.0)               # pack float ('f') into binary string
>>> fs
b'\x00\x00\x80?'

>>> bval = list( unpack('BBBB', fs)) # use list() so mutable list 
>>> bval
[0, 0, 128, 63]
>>> bval[1]=12                # mutate it (byte in middle of mantissa bits)

>>> fs = pack('BBBB', *bval)  # back to a binary string after mutation
>>> fs
b'\x00\x0c\x80?'

>>> fnew=unpack('f',fs)  # and let's look at that slightly altered float value
>>> fnew                 # NB it is a tuple of values, just one in this case
(1.0003662109375,)

unpack 需要格式正确的字符串长度。如果您正在使用缓冲区,您可以使用 unpack_from( fmt, buffer, offset),其中 offset 默认为 0,并且要求 buffer 至少 足够长。

对于那些对此感兴趣的人,最后的功能是 double-precision:

from struct import *

def bitflip(x,pos):
    fs = pack('d',x)
    bval = list(unpack('BBBBBBBB',fs))
    [q,r] = divmod(pos,8)
    bval[q] ^= 1 << r
    fs = pack('BBBBBBBB', *bval)
    fnew=unpack('d',fs)
    return fnew[0]

对于 single-precision:

def bitflip(x,pos):
    fs = pack('f',x)
    bval = list(unpack('BBBB',fs))
    [q,r] = divmod(pos,8)
    bval[q] ^= 1 << r
    fs = pack('BBBB', *bval)
    fnew=unpack('f',fs)
    return fnew[0]