【问题标题】:Group binary bits together将二进制位组合在一起
【发布时间】:2014-05-03 00:42:24
【问题描述】:

我有一个数字列表(这里是一个 4 位数字的例子,但我想用 16 位整数来做):

L = [0b1000,0b1100,0b1111,0b1001, 0b0000]

我想将所有第 1 位组合在一起,然后将所有第 2 位组合在一起,然后将所有第 3 位组合在一起,等等,如下所示:

out = 0b11110011000010000110

此解决方案(由@markcial 提出)有效:

print [[a[i] for a in [format(b,'04b') for b in L]] for i in range(4)]
#[['1', '1', '1', '1', '0'], ['0', '1', '1', '0', '0'], ['0', '0', '1', '0', '0'], ['0', '0', '1', '1', '0']]

但我想避免字符串格式化来执行这些二进制操作。

如何在不使用字符串格式的情况下将位组合在一起?

【问题讨论】:

  • 你以后还能用一些字符串方法把结果转换成整数吗?或者根本就不是字符串?
  • @PauloBu,如果可能的话,我想避免使用字符串:对每个位操作使用字符串字符就像将内存使用量乘以 8(每个字符串字符使用 8 位)

标签: python binary bit-manipulation


【解决方案1】:

也许这个算法适合你的需要,我会用 4 位数字解释它,你以后可以扩展它以使用 16 位。

L = [0b1000,0b1100,0b1111,0b1001, 0b0000]
bits = 4  # total bits
next_bit = bits*len(L)-1  # next position to be calculated
res = 0

for i in range(bits-1,-1,-1):  # iterate 3,2,1,0 (bits backwards)
    for x in L:                # iterate through every integer in L
        res = res | (((x&1<<i)>>i)<<next_bit)  # say what? o.O
        next_bit-=1            # set next_bit to the next position to be calculated

 >>> bin(res)
'0b11110011000010000110'

基本上,它的作用是遍历每个位位置以在每个数字中进行分析,然后遍历每个数字以分析该位置,一旦您知道要分析哪个数字的哪个位置,您就执行这个奇怪的计算:@ 987654322@.

循环将在res 上累积我解释的计算结果:

  1. x&amp;1&lt;&lt;i 将测试位置 i 的位是否打开
  2. ((x&amp;1&lt;&lt;i)&gt;&gt;i) 向后移动 i 位将确保结果为 10
  3. (((x&amp;1&lt;&lt;i)&gt;&gt;i)&lt;&lt;next_bit) 向前移动 next_bit 会将位设置为 10 在位置 next_bit

你需要这个next_bit 整数来记录你需要设置的结果的下一位是什么。例如,由于您有 5 个四位数字,因此您知道结果将有 5*4 位。

我不太喜欢这两个 for 循环。在 C 中这可能很好,但在 Python 中它们不是很有效。我还在想办法去掉它们。我敢于用这个简单的 oneliner 对它们进行基准测试:

>>>L = [0b1000,0b1100,0b1111,0b1001, 0b0000]
>>>int(''.join(['1' if x&1<<i else '0' for i in range(3,-1,-1) for x in L]),2)
995462

您会对性能感到惊讶。

希望这会有所帮助!

【讨论】:

  • 非常感谢!我试图了解它是如何工作的......有没有办法将输出作为二进制数据存储到字节中(即每次我们有 8 位时,我们将其打包成一个字符/字节)所以最后我们有一个(不可读)字节字符串?
  • 嗯,不太明白你在做什么。在第一个算法中,我们正在计算一个数字,该数字也可以通过一些位旋转来打包成 8 位字符。我认为 python arraystruct 中也有一些模块可以帮助您解决这个问题。
【解决方案2】:

感谢与@PauloBu 的合作,这就是我一直在寻找的东西(我承认我的问题有点不清楚):输出数字被打包成字节(8 位)以便于写入文件:

import struct
L = [0b1000,0b1100,0b1111,0b1001, 0b0000]
bits = 4
res = 0
processed_bits = 0
s = ''
for i in range(bits-1,-1,-1): 
    for x in L: 
        res = res | (((x&1<<i)>>i) << (7-processed_bits))  
        processed_bits += 1           
        if processed_bits == 8:
            s += struct.pack('B', res)
            res = 0
            processed_bits = 0

with open('blah.bin', 'wb') as f:
    f.write(s)

【讨论】:

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