使用bit twiddling计算比参数大2的最近幂的解释

时间:2017-09-17 21:00:52

标签: java bit-manipulation

这是一个众所周知的函数,用于为正参数计算下一个最接近的2的幂。然而,我没有多少经验可以理解它背后的逻辑/理论。您能否解释为何以及如何运作?特别是,选择1,2,4,8,16进行转移,如果参数的范围更大,那么将使用什么,例如,长期?为什么逻辑转换而不是算术,最后,ORing转移arg完成了什么?

static int lowestPowerOfTwoGreaterThan(int arg) {
    arg |= (arg >>>  1);
    arg |= (arg >>>  2);
    arg |= (arg >>>  4);
    arg |= (arg >>>  8);
    arg |= (arg >>> 16);
    return ++arg;
}

1 个答案:

答案 0 :(得分:1)

如果跟踪值的更改,这非常简单。 2的幂只有一个设置位,例如1001000000010000000000,这意味着2的幂,减1,是1的序列,例如1。 10000 - 1 = 1111。那么函数所做的是将任何数字更改为1的序列(不移动其最高的1位)然后添加一个,例如1。它将10000001000111001(66105)更改为11111111111111111(131071)并添加一个以生成100000000000000000(131072)。

首先,它将值自身向右移1位。这样可以延长值中1的所有行程。

   10000001000111001
OR 01000000100011100
   =================
   11000001100111101

你现在注意到每次运行的零之前至少有两个1,所以我们可以通过移位两位而不是一位来加速处理。

   11000001100111101
OR 00110000011001111
   =================
   11110001111111111

现在,每次运行的零后面至少有四个,所以我们这次换四次,然后再次运算OR。

   11110001111111111
OR 00001111000111111
   =================
   11111111111111111

重复此逻辑,下一个移位距离将为8,然后是16(此处停止为32位值),然后是32(此处停止为64位值)。对于这个例子,结果对于进一步的移位保持不变,因为它已经是一系列的。

此方法将任何二进制数更改为1的序列。如前所述,在此处加1会产生下一个最大的2的幂。