了解功能:
int64_t lstbt(int64_t val){
int64_t msk = val&(val-1);
return log2(val^msk);
}
让我们把它分成更小的块。
首先声明val-1,通过将-1 添加到val,您翻转(以及其他)最低有效位(LSB),(ie, 0 变成@ 987654326@,反之亦然)。
下一个操作 (val&(val-1)) 按位应用“与”。从& 运算符我们知道:
1 & 1 -> 1
1 & 0 -> 0
0 & 1 -> 0
0 & 0 -> 0
要么
-
val 最初是 ...0,val - 1 是 ....1,在这种情况下,val&(val-1) 产生 ...0;
-
或者var最初是...1,而var - 1是....0,在这种情况下val&(val-1)产生...0;。
所以在这两种情况下,val&(val-1) 设置为 0 LSB 的 var。除此之外,val&(val-1) 所做的另一个重要更改是设置为0,最右边的第一个位设置为1。
所以让我们说 val = xxxxxxxx10000(它可能是 xxxxxxxxx1000,只要它显示设置为 1 的最右边的位),当 msk=val&(val-1) 然后 msk将是xxxxxxxx00000
接下来,我们有val ^ msk; XOR 位运算,我们知道:
1 ^ 1 -> 0
1 ^ 0 -> 1
0 ^ 1 -> 1
0 ^ 0 -> 0
所以因为val 将类似于xxxxxxxx10000 和msk xxxxxxxx00000,其中val 中用“x”表示的位将与msk 中的位完全匹配; val ^ msk 的结果将始终是一个所有位都设置为 0 的数字,唯一的 bit 除外,它在 val 和 msk 之间会有所不同,即最右边的位设置为 1 val.
因此,val ^ msk 的结果将始终是 2 的幂(val 为 0 时除外)。可以用2^y = x 表示的值,其中y 是val 中设置为1 的最右边位的索引,x 是val^msk 的结果。因此,log2(val^msk) 会返回 y 即在val 中设置为 1 的最右边位的索引。