我正在python中读取二进制文件,文件格式的文档说:
标志(二进制)含义
1 nnn nnnn表示要跟随一个数据字节 这是要复制nnn nnnn(127最大) 次。
0 nnn nnnn表示图像中有nnn nnnn个字节 要遵循的数据(最多127个字节)和那个 没有重复。
<000> n 000 0000行结束字段。表示一行的结尾 记录。 n的值可以是0或1。 请注意,行尾字段是必需的 它反映在行记录的长度上 上面提到的领域。
在阅读文件时,我希望我所在的字节返回1 nnn nnnn
,其中nnn nnnn
部分应为50。
我已经能够使用以下方法执行此操作:
flag = byte >> 7
numbytes = int(bin(byte)[3:], 2)
但是,numbytes计算感觉就像一个廉价的解决方法。
我可以做更多的数学运算来完成numbytes的计算吗?
你会怎么做?
答案 0 :(得分:11)
检查是否设置位的经典方法是使用二进制“和”运算符,即
x = 10 # 1010 in binary
if x & 0b10: # explicitly: x & 0b0010 != 0
print('First bit is set')
要检查是否设置了第n位,请使用2的幂或更好的位移
def is_set(x, n):
return x & 2 ** n != 0
# a more bitwise- and performance-friendly version:
return x & 1 << n != 0
is_set(10, 1) # 1 i.e. first bit - as the count starts at 0-th bit
>>> True
答案 1 :(得分:10)
您可以使用掩码和文件中的字节去掉前导位。这将为您留下剩余位的值:
mask = 0b01111111
byte_from_file = 0b10101010
value = mask & byte_from_file
print bin(value)
>> 0b101010
print value
>> 42
在进行位掩码时,我发现二进制数比十六进制更容易理解。
编辑:您的用例稍微更完整的示例:
LEADING_BIT_MASK = 0b10000000
VALUE_MASK = 0b01111111
bytes = [0b10101010, 0b01010101, 0b0000000, 0b10000000]
for byte in bytes:
value = byte & VALUE_MASK
has_leading_bit = byte & LEADING_BIT_MASK
if value == 0:
print "EOL"
elif has_leading_bit:
print "leading one", value
elif not has_leading_bit:
print "leading zero", value
答案 2 :(得分:1)
如果我正确阅读了你的描述:
if (byte & 0x80) != 0:
num_bytes = byte & 0x7F
答案 3 :(得分:0)
不确定我是否正确,但如果我这样做,这应该可以解决问题:
>>> x = 154 #just an example
>>> flag = x >> 1
>>> flag
1
>>> nb = x & 127
>>> nb
26
答案 4 :(得分:0)
你可以这样做:
def GetVal(b):
# mask off the most significant bit, see if it's set
flag = b & 0x80 == 0x80
# then look at the lower 7 bits in the byte.
count = b & 0x7f
# return a tuple indicating the state of the high bit, and the
# remaining integer value without the high bit.
return (flag, count)
>>> testVal = 50 + 0x80
>>> GetVal(testVal)
(True, 50)
答案 5 :(得分:0)
class ControlWord(object):
"""Helper class to deal with control words.
Bit setting and checking methods are implemented.
"""
def __init__(self, value = 0):
self.value = int(value)
def set_bit(self, bit):
self.value |= bit
def check_bit(self, bit):
return self.value & bit != 0
def clear_bit(self, bit):
self.value &= ~bit
答案 6 :(得分:0)
而不是int(bin(byte)[3:],2),你可以简单地使用:int(bin(byte&gt;&gt; 1),2)