【问题标题】:How to Count Bits from multiple Hexadecimals如何计算多个十六进制的位
【发布时间】:2023-03-30 07:34:01
【问题描述】:

我有 16 个十六进制值,我需要计算位(1)的总数

#I have tried this

val = hex(bus.read_port(0))+hex(bus.read_port(1)) #There are 16 ports.

#read port returns a Decimal (0-255)
#val is 0x3f0xff

def bitCount(val):
    count = bin(val).count('1')
    return (count)

#bitCount() Returns 6 instead of 14

但它只返回第一个字节的位。 在返回之前打印 val 例如0x3f0xff 我需要的是 3F00FF (每个十六进制的二进制值串成一个十六进制) 或另一种读取组合位数的方式。

这似乎可行,但我得到 10 而不是 16

bus.write_port(0, 0xFF)
bus.write_port(1, 0xFF)

def popcount255(k):
    k = (k & 15) + (k >> 4)
    k = (k & 3) + (k >> 2)
    return (k & 1) + (k >> 1)

def bitCount():
    result = popcount255(bus.read_port(0)) + popcount255(bus.read_port(1))
    return (result)

if True:
    print "BitCount ", bitCount()

我数到了 10?

现在可以使用了

def bitCount():
    result = bin(bus_1.read_port(0)).count('1') + bin(bus_1.read_port(1)).count('1')
return (result)

【问题讨论】:

  • 好吧0x3f0xff 没有任何意义。
  • 将原始问题备份起来对您很有帮助,然后是您的其他代码和有关使 @WillemVanOnsem 的方法起作用的问题。

标签: python binary hex


【解决方案1】:

这里有一些奇怪的东西:

  1. 数字是表示为十进制还是十六进制,在计算设置位时并不重要;
  2. 通过使用hex(..) 将其转换为字符串;和
  3. 稍后您将这些字符串连接起来,使结果不是十六进制值。

我们可以在 O(log k) 中实现一个 popcount 用于高达 255(或常量 k 位)的值:

def popcount255(k):
    k = (k & 85) + ((k & 170) >> 1)
    k = (k & 51) + ((k & 204) >> 2)
    return (k & 15) + ((k & 240) >> 4)

所以我们可以使用这个函数来计算设置的位数:

result = <b>popcount255(</b>bus.read_port(0)<b>)</b> + <b>popcount255(</b>bus.read_port(1)<b>)</b>

【讨论】:

  • 我正在尝试你的方法。
  • 我认为您的popcount255 有问题。 popcount255(0b111) 给了我 2。还是我遗漏了一些明显的东西? OP 的 bin(k).count('1') 在我看来还不错 - 只要你给它一个 int。
  • @PaulPanzer:你是对的。我或多或少地反向实现了算法。现在应该修复了。
  • 有趣的算法。我认为它是“伪”-O(log k),一旦超过架构int 的位长度,实际上是线性的?没有批评,只是好奇。
  • @PaulPanzer:是的,因为在 Python-3.x 中,按位运算适用于任意长度的数字。但是如果int的位数是固定的,并且按位运算是常数时间,那么算法可以推广到O(log k)运算。
【解决方案2】:

您无需转换为十六进制字符串即可获得位数,只需将两个值直接转换为二进制字符串,计算每个值中的 1,然后将两个结果相加即可:

bitCount = bin(bus.read_port(0)).count('1') + bin(bus.read_port(1)).count('1')

或者,如果你真的想计算 val = '0x3FFF' 以传递给你原来的 bitCount() 函数,你可以这样做:

val = hex((bus.read_port(0) << 8) + bus.read_port(1))

像这样工作:

  --> hex((0x3F << 8) + 0xFF)
  --> hex(0x3F00 + 0xFF)
  --> hex(0x3FFF)
  --> '0x3FFF'

你正在做的是连接两个十六进制字符串,因此你的问题:

val = hex(bus.read_port(0)) + hex(bus.read_port(0))

  --> hex(0x3F) + hex(0xFF)
  --> '0x3F' + '0xFF'        # string concatenation
  --> '0x3F0xFF'             # not '0x3FFF', extra '0x' in the middle

请注意,'0x3F0xFF' 不是十六进制数字的有效字符串表示形式(尝试使用 bin() 将其转换为二进制时,只会在中间出现意外的 '0x' 之前看到第一个 '0x3F' 部分,因此为什么count('1') 正在返回 6)。

【讨论】:

  • 谢谢你完美地完成了我想做的事情,没想到你可以那样做。
  • 很高兴能帮上忙!如果您觉得对您有用,请随时 accept my answer :-)
猜你喜欢
  • 1970-01-01
  • 2019-04-16
  • 1970-01-01
  • 2021-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-29
  • 1970-01-01
相关资源
最近更新 更多