【问题标题】: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 上的精选内容。
  • @GrijeshChauhan 您能否详细说明这比number % 2 == 0 快多少??

标签: java methods arraylist boolean int


【解决方案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

            【讨论】:

              猜你喜欢
              • 2017-05-25
              • 2013-08-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-04-25
              • 2015-12-27
              • 2018-09-25
              • 1970-01-01
              相关资源
              最近更新 更多