这个布尔值“(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 == 0
和1 == 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 不应该在那个表达式的某处有log
或2^
吗?【参考方案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) == 0
是true
,这意味着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;
【讨论】:
&
也是逻辑与。 &&
会短路,而&
不会。
number % 2
与 number & 1
不同,如果 number
为负数。
如果你被传递一个负长度,那么你有更大的问题! ;)
@RyanAmos "迭代每一位?"按位与是我见过的每个 CPU 中的单一操作 - 它是并行执行的最简单的事情之一。
@MitchWheat 没有理由抛出 number < 0
案例 - 虽然奇数负数 mod 2 为 -1,偶数 mod 2 仍为 0。【参考方案4】:
这个表达式的意思是“整数代表偶数”。
原因如下:十进制1
的二进制表示为00000000001
。所有奇数都以二进制的1
结尾(这很容易验证:假设数字的二进制表示不以1
结尾;那么它由2 的非零幂组成,它始终是偶数)。当你用奇数做二进制AND
时,结果是1
;当你用偶数做二进制AND
时,结果是0
。
当优化器很差甚至不存在时,这曾经是决定奇数/偶数的首选方法,%
运算符需要的周期数是 &
运算符的 20 倍。如今,如果您执行number % 2 == 0
,编译器可能生成的代码执行速度与(number & 1) == 0
一样快。
【讨论】:
【参考方案5】:单个&
表示按位and
运算符不比较
所以这段代码检查第一个bit
(最低有效/最右边)是否设置,这表明数字是否为odd
;因为所有奇数都将以1
在最低有效位结束,例如xxxxxxx1
【讨论】:
请注意,如果您想避免像f(x) & g(x)
这样的表达式产生副作用,单个 &
可以用作逻辑 and
【参考方案6】:
&
是按位运算AND
。
对于数字 = 8:
1000
0001
& ----
0000
结果是(8 & 1) == 0
。所有偶数都是这种情况,因为它们是 2 的倍数,并且从右边开始的第一个二进制数字始终是 0。1 的二进制值是 1,前导 0,所以当我们 AND
它带有偶数时,我们'剩下0。
【讨论】:
【参考方案7】:Java 中的&
运算符是位与运算符。基本上,(number & 1)
在number
和1
之间执行按位与运算。结果是 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”是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章