【问题标题】:Packed Bit Fields in PythonPython 中的打包位字段
【发布时间】:2016-01-01 08:55:28
【问题描述】:

我想将一个 10 位整数和一个 54 位整数打包成一个 64 位结构。但是这段代码最终使用了 128 位。

from ctypes import *

class ABC(Structure):
    _fields_ = [("a", c_int, 10), ("b", c_uint64, 54)]

print(sizeof(ABC) * 8) # 128

【问题讨论】:

  • 你只考虑无符号整数吗?
  • 不,签名和未签名。但如果你有一个只针对未签名的解决方案,我想看看。

标签: python memory structure bit-fields


【解决方案1】:

考虑到int_10int_54 是具有所需位数的整数:

>>> def pack(int_10, int_54):
...     return (int_10 & 0x3FF) | (int_54 & 0x3FFFFFFFFFFFFF) << 10

>>> bin(pack(1, 1))
'0b10000000001'
>>> bin(pack(1, 2 ** 54 - 1))
'0b1111111111111111111111111111111111111111111111111111110000000001'
>>> bin(pack(2 ** 10, 2 ** 54))
'0b0'

然后您可以使用struct.pack 打包生成的整数以获取字节字符串。

>>> import struct
>>> struct.pack('Q', pack(2 ** 10 - 1, 2 ** 54 - 1))
'\xff\xff\xff\xff\xff\xff\xff\xff'

【讨论】:

  • 这适用于压缩数据以进行存储等。但它不会让我轻松操作位字段,例如:x=ABC(10,20);x.a=-15;x.b=50 我真的在寻找 Python 的内置功能,如果它存在的话。
【解决方案2】:

无论出于何种原因,当您将不同宽度的对象混合到同一个字节中时,ctypes 不会正确地进行位打包。像这样的东西似乎对我有用:

class ABC(Structure):
   _pack_ = 1
   _fields_ = [("a",c_int64,10),("b",c_uint64,54)]

【讨论】:

猜你喜欢
  • 2014-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多