这个布尔值“(number & 1) == 0”是啥意思?

Posted

技术标签:

【中文标题】这个布尔值“(number & 1) == 0”是啥意思?【英文标题】:What does this boolean "(number & 1) == 0" mean?这个布尔值“(number & 1) == 0”是什么意思? 【发布时间】:2013-02-01 01:46:27 【问题描述】:

On CodeReview我发布了一段工作代码,并要求提供改进它的提示。我得到的一个方法是使用布尔方法来检查 ArrayList 是否具有偶数个索引(这是必需的)。这是建议的代码:

private static boolean isEven(int number)

    return (number & 1) == 0;

由于我已经纠缠该特定用户以寻求很多帮助,因此我决定是时候纠缠 SO 社区了!我真的不明白这是如何工作的。该方法被调用,并将 ArrayList 的大小作为参数(即 ArrayList 有十个元素,number = 10)。

我知道一个 & 运行数字和 1 的比较,但之后我就迷路了。

按照我的阅读方式,如果number == 01 == 0 则返回true。我知道第一个不是真的,后者显然没有意义。有人可以帮帮我吗?

编辑:我可能应该补充一点,代码确实有效,以防有人想知道。

【问题讨论】:

有谁知道谁把这个链接到另一个帖子(这与这些东西无关)?我可以以某种方式删除它吗? 该死的,这真的很聪明! 这是 Twitter 上的精选内容。 @AndrewMartin twitter.com/StackExchange/status/302768803719286785 @GrijeshChauhan 您能否详细说明这比number % 2 == 0 快多少?? 【参考方案1】:

请记住,“&”是按位运算。您可能知道这一点,但根据您提出问题的方式,我并不完全清楚。

话虽如此,理论上的想法是你有一些 int,它可以通过一些 1 和 0 的序列以位表示。例如:

...10110110

在二进制中,因为它是以 2 为底,所以当数字的按位版本以 0 结尾时,它是偶数,而当它以 1 结尾时,它是奇数。

因此,用 1 对上述进行按位 & 是:

...10110110 & ...00000001

当然,这是0,所以你可以说原来的输入是偶数。

或者,考虑一个奇数。例如,将 1 添加到我们上面的内容中。那么

...10110111 & ...00000001

等于 1,因此不等于 0。瞧。

【讨论】:

谢谢 - 你的解释很清楚。另外,任何以 Voila 结尾的答案都值得一票。 应该也知道这个答案中的负数。 另外,我可能会修改这个答案以包括 n%k == n&(k-1) 对所有 k 的事实,这是 2 的正幂。这可能不是提问者所要求的,但它很方便要知道的事情。 @fluffy 并不是说​​它不起作用,但并不是每个人都知道二进制补码。 @fluffy 不应该在那个表达式的某处有log2^ 吗?【参考方案2】:

您可以通过二进制表示中的最后一位来确定数字是偶数还是奇数:

1 -> 00000000000000000000000000000001 (odd)
2 -> 00000000000000000000000000000010 (even)
3 -> 00000000000000000000000000000011 (odd)
4 -> 00000000000000000000000000000100 (even)
5 -> 00000000000000000000000000000101 (odd)
6 -> 00000000000000000000000000000110 (even)
7 -> 00000000000000000000000000000111 (odd)
8 -> 00000000000000000000000000001000 (even)

& 两个整数之间是按位与运算符:

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

所以,如果(number & 1) == 0true,这意味着number 是偶数。


假设number == 6,那么:

6 -> 00000000000000000000000000000110 (even)

     &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

1 -> 00000000000000000000000000000001

-------------------------------------

0 -> 00000000000000000000000000000000

number == 7:

7 -> 00000000000000000000000000000111 (odd)

     &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

1 -> 00000000000000000000000000000001

-------------------------------------

1 -> 00000000000000000000000000000001

【讨论】:

【参考方案3】:

& 是按位与运算符。 && 是逻辑与运算符

在二进制中,如果设置了数字位(即一),则数字为奇数。

在二进制中,如果数字位为零,则数字为偶数。

(number & 1) 是数字位的按位 AND 测试。

另一种方法(可能效率较低但更容易理解)是使用模运算符%

private static boolean isEven(int number)

    if (number < 0)
       throw new ArgumentOutOfRangeException();

    return (number % 2) == 0;

【讨论】:

&amp; 也是逻辑与。 &amp;&amp; 会短路,而&amp; 不会。 number % 2number &amp; 1 不同,如果 number 为负数。 如果你被传递一个负长度,那么你有更大的问题! ;) @RyanAmos "迭代每一位?"按位与是我见过的每个 CPU 中的单一操作 - 它是并行执行的最简单的事情之一。 @MitchWheat 没有理由抛出 number &lt; 0 案例 - 虽然奇数负数 mod 2 为 -1,偶数 mod 2 仍为 0。【参考方案4】:

这个表达式的意思是“整数代表偶数”。

原因如下:十进制1 的二进制表示为00000000001。所有奇数都以二进制的1 结尾(这很容易验证:假设数字的二进制表示不以1 结尾;那么它由2 的非零幂组成,它始终是偶数)。当你用奇数做二进制AND时,结果是1;当你用偶数做二进制AND时,结果是0

当优化器很差甚至不存在时,这曾经是决定奇数/偶数的首选方法,% 运算符需要的周期数是 &amp; 运算符的 20 倍。如今,如果您执行number % 2 == 0,编译器可能生成的代码执行速度与(number &amp; 1) == 0 一样快。

【讨论】:

【参考方案5】:

单个&amp; 表示按位and 运算符比较

所以这段代码检查第一个bit(最低有效/最右边)是否设置,这表明数字是否为odd;因为所有奇数都将以1 在最低有效位结束,例如xxxxxxx1

【讨论】:

请注意,如果您想避免像 f(x) &amp; g(x) 这样的表达式产生副作用,单个 &amp; 可以用作逻辑 and 【参考方案6】:

&amp; 是按位运算AND

对于数字 = 8:

  1000
  0001
& ----
  0000

结果是(8 &amp; 1) == 0。所有偶数都是这种情况,因为它们是 2 的倍数,并且从右边开始的第一个二进制数字始终是 0。1 的二进制值是 1,前导 0,所以当我们 AND 它带有偶数时,我们'剩下0。

【讨论】:

【参考方案7】:

Java 中的&amp; 运算符是位与运算符。基本上,(number &amp; 1)number1 之间执行按位与运算。结果是 0 或 1,取决于它是偶数还是奇数。然后将结果与 0 进行比较,判断是否为偶数。

这是page describing bitwise operations。

【讨论】:

【参考方案8】:

它正在执行二进制和反对1,如果没有设置最低有效位,则返回0

你的例子

00001010 (10)

00000001 (1)

============

00000000 (0)

【讨论】:

【参考方案9】:

这是逻辑设计概念按位 & (AND) 运算符。

返回 ( 2 & 1 );表示 - 将值转换为按位数字并比较 (AND) 特征并返回值。

首选此链接http://www.roseindia.net/java/master-java/java-bitwise-and.shtml

【讨论】:

以上是关于这个布尔值“(number & 1) == 0”是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个 if 语句不返回布尔值?

如何在 if 语句中使用这个布尔值?

为啥这个数组到二维数组布尔值是真的?

如何输入布尔值并作为布尔值返回?

在js 中怎样声明一个布尔值变量,使其经过多次验证,最后返回这个布尔

React JS Typescript usestate 与布尔值