【问题标题】:Get the bit number that differs between two (binary) numbers获取两个(二进制)数字之间不同的位数
【发布时间】:2012-09-11 18:03:07
【问题描述】:

我有两个数字(二进制​​或非二进制,没有任何作用),它们只有一位不同,例如(伪代码)

a = 11111111
b = 11011111

我想要一个简单的 python 函数,它返回不同的位位置(给定示例中的“5”,从右到左看)。我的解决方案是(python)

math.log(abs(a-b))/math.log(2)

但我想知道是否有更优雅的方法来做到这一点(不使用浮点数等)。

谢谢 亚历克斯

【问题讨论】:

  • 尝试使用按位异或代替 abs(a-b)

标签: python math binary


【解决方案1】:

你可以使用二进制独占:

a = 0b11111111
b = 0b11011111

diff = a^b  # 0b100000
diff.bit_length()-1 # 5 (the first position (backwards) which differs, 0 if a==b )

【讨论】:

  • 使用(a^b).bit_length() - 1代替字符串长度。(应该在python2.7+中工作)。
  • 单行解决方案是最好的。谢谢!
  • @Alex (a^b).bit_length()-1 :)
【解决方案2】:

除非我错过了什么......

这应该可行:

>>> def find_bit(a,b):
    a = a[::-1]
    b = b[::-1]
    for i in xrange(len(a)):
        if a[i] != b[i]:
            return i
    return None

>>> a = "11111111"
>>> b = "11011111"
>>> find_bit(a,b)
5

也许不是那么优雅,但它很容易理解,并且可以完成工作。

【讨论】:

    【解决方案3】:

    如果不使用按位运算,您可以执行以下操作:

    In [1]: def difbit(a, b):
       ...:     if a == b: return None
       ...:     i = 0
       ...:     while a%2 == b%2:
       ...:         i += 1
       ...:         a //= 2
       ...:         b //= 2
       ...:     return i
       ...: 
    
    In [2]: difbit(0b11111111, 0b11011111)
    Out[2]: 5
    

    【讨论】:

      【解决方案4】:

      使用(a^b).bit_length()-1 非常适合只有一个差异位的数字。例如:

      a = 1000000
      b = 1000001
      (a^b).bit_length()-1
      Output: 0
      

      但是对于具有多个差异位的数字,它给出了最左边差异位的索引。例如:

      a = 111111111111111111111111111111
      b = 111111110111011111111111111111
      c = a^b   # 1000100000000000000000
      c.bit_length()-1
      Output: 21  # Instead of 17. 21 is the left most difference bit
      

      所以要解决这个问题,我们需要隔离最右边的设置位,然后获取它的索引。因此,使用((a^b) & (-(a^b))).bit_length()-1 最适合所有输入:

      c = (a^b) & (-(a^b))   # 100000000000000000 - Isolates the rightmost set bit
      c.bit_length()-1
      Output: 17
      (a^b) & (-(a^b))).bit_length()-1
      Output: 17
      

      了解如何从here 中分离出最右边的设置位

      【讨论】:

      • 我已经测试了我的答案的结果并且它工作正常。
      猜你喜欢
      • 2021-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-09
      • 2014-06-19
      • 2022-11-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多