大于等于8的最小的2的倍数是8
大于等于9的最小的2的倍数是16
v--
v |= v >> 1
v |= v >> 2
v |= v >> 4
v |= v >> 8
v |= v >> 16
v++
如果v的二进制是:0000 1000,那么就找最前面的1的位置,其余置0就行
如果v的二进制是:0000 1010,那么就找最前面的1之前的一个位置,其余置0.
总之,如果v本身就是2的倍数,返回它,否则找最前面的1之前的位置,其余置0.
上面代码中,v++之前要做的工作就是将最高位之后的位都变成1,v–是为了应对v本身就是2的倍数这种情况,减1之后最高位就变成后面那位了,中间右移然后或运算就是把最高位后面的0变为1.
下面以v==8和v==9为例:
v==8
1000
v-- 0111
v|=v>>1 0111
v|=v>>2 0111
v|=v>>4 0111
v|=v>>8 0111
v|=v>>16 0111
v++ 1000
v==9
1001
v-- 1000
v|=v>>1 1100
v|=v>>2 1111
v|=v>>4 1111
v|=v>>8 1111
v|=v>>16 1111
v++ 1 0000