有人可以解释一下这些代码行在做什么吗?


int64_t lstbt(int64_t val){ 
int64_t msk = val&(val-1); 
return log2(val^msk);
}

msk实际计算什么,为什么我们要返回logxormsk

要理解函数:

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))按位应用"and"。从&运算符中我们知道:

1 & 1  -> 1
1 & 0  -> 0
0 & 1  -> 0
0 & 0  -> 0

所以要么

  1. val最初是...0val - 1是....1,在这种情况下val&(val-1)产生...0;

  2. 或者var最初是...1var - 1是....0,在本例中val&(val-1)产生...0;。

因此,在这两种情况下,val&(val-1)都设置为0varLSB。除此之外,val&(val-1)所做的另一个重要更改是设置为0最右边的第一个位设置为1.

因此,假设 val = xxxxxxxx 1 0000(只要它显示最右边设置为1的最位,就可以xxxxxxxxx1000),当msk=val&(val-1)时,msk将被xxxxxxxx00000

接下来,我们有val ^ msk;一个XOR位运算,我们知道:

1 ^ 1  -> 0
1 ^ 0  -> 1
0 ^ 1  -> 1
0 ^ 0  -> 0

所以因为val会像xxxxxxxx10000和 mskxxxxxxxx00000,其中用val的 'x' 表示的位将与msk的位完全匹配;val ^ msk的结果将始终是一个数字,所有位都设置为0除了唯一在valmsk之间不同的bit, 即最右边设置为val1

因此,val ^ msk的结果将始终是 2 的幂值(val为 0 时除外)。可以用2^y = x表示的值,其中y是设置为1的最右位的索引valxval^msk的结果。因此,log2(val^msk)返回y即最右边位的索引设置为 1 inval

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可以在提醒 2 上除以多少次 0。

相关内容

  • 没有找到相关文章

最新更新