80

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

private static boolean isEven(int number)
{
    return (number & 1) == 0;
}

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

我知道单&次运行数字和 1 的比较,但在那之后我迷路了。

我读它的方式是说 return true if number == 0and 1 == 0。我知道第一个不是真的,后者显然没有意义。有人可以帮帮我吗?

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

4

9 回答 9

115

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

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

...10110110

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

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

...10110110 & ...00000001

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

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

...10110111 & ...00000001

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

于 2013-02-16T00:49:16.977 回答
70

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

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
于 2013-02-16T01:08:50.753 回答
18

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

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

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

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

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

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

    return (number % 2) == 0;
}
于 2013-02-16T00:45:00.387 回答
8

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

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

在优化器很差甚至不存在的时候,这曾经是决定奇数/偶数的首选方法,并且%操作员需要的循环次数是操作员的二十倍&。如今,如果您这样做number % 2 == 0,编译器可能会生成执行速度一样快的代码(number & 1) == 0

于 2013-02-16T00:45:19.100 回答
5

&表示按位and运算符比较

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

于 2013-02-16T00:45:30.310 回答
4

&是按位AND运算。

对于数字 = 8:

  1000
  0001
& ----
  0000

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

于 2013-02-16T00:53:51.800 回答
3

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

这是描述按位运算的页面

于 2013-02-16T00:45:53.947 回答
3

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

对于你的例子

00001010 (10)

00000001 (1)

===========

00000000 (0)

于 2013-02-16T00:49:02.627 回答
3

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

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

更喜欢这个链接http://www.roseindia.net/java/master-java/java-bitwise-and.shtml

于 2013-02-16T07:34:00.293 回答