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

时间:2020-12-31 09:07:27

标签: c++ bit-manipulation bit bitmask

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

msk 实际计算什么,为什么我们返回值 log xormsk

2 个答案:

答案 0 :(得分:2)

了解功能:

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

所以要么

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

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

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

所以让我们说 val = xxxxxxxx10000(它可以是 1,只要它展示了设置为 1 的最右边的位),当 xxxxxxxxx1000那么 msk=val&(val-1) 将是 msk

接下来,我们有xxxxxxxx00000val ^ msk 按位运算,我们知道:

XOR

因此,因为 1 ^ 1 -> 0 1 ^ 0 -> 1 0 ^ 1 -> 1 0 ^ 0 -> 0 将类似于 val 和 msk xxxxxxxx10000,其中 xxxxxxxx00000 中用 'x' 表示的位将与 {{1} 中的位完全匹配}; val 的结果将始终是一个所有位都设置为 msk 的数字,除了 val ^ msk0 之间唯一不同的 bit,即最右边的位设置为 valmsk

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

答案 1 :(得分: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 的次数。