通过0位操作清除i中的位

时间:2018-02-26 02:56:27

标签: java bit-manipulation bit

我打算破解编码面试第5章位操作 并找到了从数字num

中清除i到0的位的方法
int mask = ~(-1 >>> (31 - i));
return num & mask

虽然以上工作

我们可以像

一样简单吗?
int mask = (-1 << (i+1));
return num & mask;

我错过任何角落案件吗?

2 个答案:

答案 0 :(得分:1)

绝对。你的面具-1 << (i+1)在逻辑上等同于书的面具~(-1 >>> (31 - i))

您的方法逐位将-1向左移i + 1次,并使用i + 1填充最低0位。

本书的方法在逻辑上将-1转移到右31 - i次,用31 - i填充最高0位。然而,它然后反转位,这使得你的位相当于它。要为int的所有值验证它,您可以创建一个简单的for循环:

for (int i = 0; i < 31; i++) {
    System.out.println(~(-1 >>> (31 - i)) + " " + (-1 << (i+1)));
}

运行它时,您会发现每次迭代时两个掩码都是等效的。

答案 1 :(得分:1)

确实存在边缘情况:i = 31(-1 << (i+1)) = -1~(-1 >>> (31 - i)) = 0

这是因为移位计数以模型的大小(以位为单位)取模,在本例中为32,(31 + 1) mod 32 = 0因此在两个表达式中,有效移位计数为零。然后他们采取不同的行动,因为第二个表达式的反转逻辑。

但是,~(-1 >>> (31 - i)) 等同于更简单的-2 << i