这个布尔"(数字&1)== 0"是什么意思?

And*_*tin 76 java methods int boolean arraylist

在CodeReview上,我发布了一段代码,并询问了改进它的提示.我得到的是使用布尔方法来检查ArrayList是否具有偶数个索引(这是必需的).这是建议的代码:

private static boolean isEven(int number)
{
    return (number & 1) == 0;
}
Run Code Online (Sandbox Code Playgroud)

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

我知道一个单独&运行数字和1的比较,但在那之后我迷路了.

我读它的方式,就是说,如果number == 0和,则返回true 1 == 0.我知道第一个不是真的,后者显然没有意义.有人可以帮帮我吗?

编辑:我应该添加代码确实有效,万一有人想知道.

Kir*_*rby 112

请记住,"&"是一种按位操作.您可能已经意识到这一点,但根据您提出问题的方式,我并不完全清楚.

话虽这么说,理论上的想法是你有一些int,可以通过一些1和0的系列来表示.例如:

...10110110
Run Code Online (Sandbox Code Playgroud)

在二进制中,因为它是基数2,只要数字的按位版本以0结尾,它就是偶数,当它以1结尾时它是奇数.

因此,对于上述内容执行按位和1是:

...10110110 & ...00000001
Run Code Online (Sandbox Code Playgroud)

当然,这是0,所以你可以说原始输入是偶数.

或者,考虑一个奇数.例如,将1添加到上面的内容中.然后

...10110111 & ...00000001
Run Code Online (Sandbox Code Playgroud)

等于1,因此不等于零.瞧.

  • 谢谢 - 你的解释非常明确.此外,任何以Voila结尾的答案都值得赞成. (13认同)
  • 另外,我可能会修改这个答案,将所有`k`中的'n%k == n&(k-1)`包括为2的正幂.这可能不是提问者问的但它是一个方便的事情要知道. (3认同)
  • @AlvinWong负数也有效.-1 =`111 ... 11111`. (2认同)

Eng*_*uad 66

您可以通过其二进制表示中的最后一位确定偶数或奇数:

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

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

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
Run Code Online (Sandbox Code Playgroud)

所以,如果(number & 1) == 0true,这意味着number是均匀的.


我们假设那样number == 6:

6 -> 00000000000000000000000000000110 (even)

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

1 -> 00000000000000000000000000000001

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

0 -> 00000000000000000000000000000000
Run Code Online (Sandbox Code Playgroud)

何时number == 7:

7 -> 00000000000000000000000000000111 (odd)

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

1 -> 00000000000000000000000000000001

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

1 -> 00000000000000000000000000000001
Run Code Online (Sandbox Code Playgroud)


Mit*_*eat 17

&是按位AND运算符.&&是逻辑AND运算符

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

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

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

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

private static boolean isEven(int number)
{
    if (number < 0)
       throw new ArgumentOutOfRangeException();

    return (number % 2) == 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 如果`number`为负数,则`number%2`与`number&1`不同. (5认同)
  • 如果你被传递一个负长度,那么你有更大的问题!;) (4认同)
  • @RyanAmos"迭代每一位?" 按位AND是我见过的每个CPU中的单个操作 - 它是最简单的并行操作之一. (4认同)
  • `&`也是逻辑AND.`&&`短路,而'&`没有. (2认同)
  • @MitchWheat没有理由抛出`number <0` case - 而奇数负数mod 2是-1,偶数mod 2仍然是0. (2认同)

das*_*ght 8

该表达式表示"整数表示偶数".

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

这曾经是优化器很差到不存在时决定奇数/偶数返回的首选方法,并且%运算符需要运算符所占周期数的20倍&.现在,如果这样做number % 2 == 0,编译器可能会生成尽快执行的代码(number & 1) == 0.


iTe*_*ech 5

单一&意味着逐位and运算符而不是比较

因此,此代码检查是否设置了第一个bit(最不重要/最右),这表示该数​​字是否是odd; 因为所有奇数都将以1最低有效位结束,例如xxxxxxx1