问题描述
int64_t lstbt(int64_t val){
int64_t msk = val&(val-1);
return log2(val^msk);
}
msk
实际计算什么,为什么我们返回值 log
xor
的 msk
?
解决方法
了解功能:
int64_t lstbt(int64_t val){
int64_t msk = val&(val-1);
return log2(val^msk);
}
让我们把它分成更小的块。
首先是语句 val-1
,通过将 -1
添加到 val
,您翻转(除其他外)最低有效位 (LSB),(即 0
变为 1
,反之亦然)。
下一个操作 (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
。
所以让我们说 val = xxxxxxxx10000(它可以是 1
,只要它展示了设置为 1 的最右边的位),当 xxxxxxxxx1000
那么 msk=val&(val-1)
将是 msk
接下来,我们有xxxxxxxx00000
; val ^ msk
按位运算,我们知道:
XOR
因此,因为 1 ^ 1 -> 0
1 ^ 0 -> 1
0 ^ 1 -> 1
0 ^ 0 -> 0
将类似于 val
和 msk xxxxxxxx10000
,其中 xxxxxxxx00000
中用 'x' 表示的位将与 {{1} 中的位完全匹配}; val
的结果将始终是一个所有位都设置为 msk
的数字,除了 val ^ msk
和 0
之间唯一不同的 bit
,即最右边的位设置为 val
的 msk
。
因此,1
的结果将始终是 2 的幂的值(除非 val
为 0)。可以用val ^ msk
表示的值,其中val
是2^y = x
中设置为1的最右边位的索引,y
是{{1}的结果}}。因此,val
返回 x
即val^msk
中设置为 1 的最右边位的索引。
val&(val-1) # to figure out if value is either 0 or an exact power of two.
val^msk # cuts the part of power of 2 from val
log2 # finds the index of bit which set val^msk.
所以我猜你有 lstbt
的功能是找出 val
在提醒 0 的情况下可以除以 2 的次数。