log2在位操作中有什么作用?

时间:2019-01-04 02:54:42

标签: c++ bit-manipulation

为什么我们要使用log2来获取最右边的设置位的位置? 我听不懂整个代码在这里。非常感谢!

unsigned int getFirstSetBitPos(int n) 
{ 
    return log2(n & -n) + 1; 
} 

1 个答案:

答案 0 :(得分:2)

摘自Wikipedia上的Binary logarithm

  

在数学中,二进制对数(log 2 n )是必须将数字2求幂才能获得该值的幂 n 。也就是说,对于任何实数 x

     

x = log 2 n ⟺2 x = n

     

例如,二进制对数1为0,二进制对数2为1,二进制对数4为2,二进制对数32为5。

因此,在您的代码中,n & -n首先关闭除最初设置为1的最右边的位以外的所有 位,然后获取日志 2 结果数的>以获得2的幂(恰好与设置为1的位的从0开始的位置相同),最后在结果中加1以得到1位位置(这很奇怪,因为位通常是由从0开始的位置来代替的。)

例如,让我们看一下5。在二进制中,5是位00000000000000000000000000000101(假设是32位int类型),而-5是位11111111111111111111111111111011(假设使用2s-complement实现了负整数)。请记住,&运算符执行bitwise AND操作,只有在 both 输入中的该位为1时,该操作才返回给定位的1。数字,否则返回0。因此:

  00000000000000000000000000000101 (5)
& 11111111111111111111111111111011 (-5)
----------------------------------
  00000000000000000000000000000001 (1)

因此,5 & -5 = 1,然后是log2(1) = 00 + 1 = 1

让我们看一个更复杂的数字1041204192,它是位00111110000011111000001111100000,而-1041204192是位11000001111100000111110000100000

  00111110000011111000001111100000 (1041204192)
& 11000001111100000111110000100000 (-1041204192)
----------------------------------
  00000000000000000000000000100000 (32)

所以1041204192 & -1041204192 = 32,然后是log2(32) = 55 + 1 = 6

只是踢一下,让我们看看0

  00000000000000000000000000000000 (0)
& 00000000000000000000000000000000 (-0)
----------------------------------
  00000000000000000000000000000000 (0)

因此0 & -0 = 0log2(0)-INFINITY,对于整数,该值未定义

这里是-1

  11111111111111111111111111111111 (-1)
& 00000000000000000000000000000001 (--1)
----------------------------------
  00000000000000000000000000000001 (1)

所以(-1) & -(-1) = 1,然后是log2(1) = 00 + 1 = 1

还有-2

  11111111111111111111111111111110 (-2)
& 00000000000000000000000000000010 (--2)
----------------------------------
  00000000000000000000000000000010 (2)

所以(-2) & -(-2) = 2,然后是log2(2) = 11 + 1 = 2

依此类推...