这是一个众所周知的函数,用于为正参数计算下一个最接近的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;
}
答案 0 :(得分:1)
如果跟踪值的更改,这非常简单。 2的幂只有一个设置位,例如100
,10000000
,10000000000
,这意味着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的幂。