我在我的代码中经常使用($var & 1)
,如果$var
是奇数则返回true,如果是偶数则返回false。
但是"&"到底是什么意思呢?
我在我的代码中经常使用($var & 1)
,如果$var
是奇数则返回true,如果是偶数则返回false。
但是"&"到底是什么意思呢?
& 是二进制的 and
运算符。如果您有一个二进制值,并且使用另一个二进制值进行 and
运算,则结果将是两个值的按位 and
运算结果。例如:
01101010
& 01011001
= 01001000
最右边的二进制位是1时(这种情况下该数字为奇数),或者它是0时(此时该数字为偶数)。如果您将一个数字与1 &
运算,则只查看最低有效位,然后检查该数字是否为1或0。正如其他人所提到的,查看按位运算符以获取有关它们工作方式的信息。
$is_even = $x % 2 === 0; $is_odd = !$is_even;
。 - Toskan二进制系统中的两个基本运算是 OR 和 AND。
OR 意味着“如果 A 或 B 任意一个为 1(表示开),则输出 1”。一个现实世界的例子是平行接通的两个电灯开关。只要其中任何一个开关打开,电流就可以通过。
AND 意味着“如果 A 和 B 都为 1,则输出 1”。实际世界中的例子是串接的两个电灯开关。只有当两个开关都打开时,电流才能通过。
在计算机中,这些不是物理开关,而是半导体,它们的功能被称为 逻辑门。它们执行与开关相同类型的操作 - 响应电流或无电流。
当应用于整数时,每个数字中的每个位都会与另一个数字中的每个位相结合。因此,要理解按位运算符 OR 和 AND,您需要将数字转换为二进制,然后对每对匹配的位执行 OR 或 AND 运算。
这就是为什么:
00011011 (odd number)
AND
00000001 (& 1)
==
00000001 (results in 1)
尽管
00011010 (even number)
AND
00000001 (& 1)
==
00000000 (results in 0)
因此,(& 1) 操作使用AND逻辑将最右边的位与1进行比较。其他所有位都被忽略,因为任何东西与无所谓是无关紧要的。在二进制中,偶数也是十进制中的偶数(10是2的倍数)。& means AND,
| means OR,
~ means NOT, and
^ means XOR.
其他的可以通过组合这些来完成,例如:~ (a & b) is equivalent to a NAND operation
PHP特别提示
按位运算符不适用于浮点数,在PHP中,浮点数将隐式转换为整数。表示为整数的范围之外的数字将截断为零 - 也就是说,所有大于PHP_INT_MAX的数字在表达式 ($num & 1)
中看起来都是“偶数”。如果您想支持PHP_INT_MIN / PHP_INT_MAX之外的数字,则需要使用fmod($num, 2)
。但是,如果您使用的是64位PHP,则整数的精度比浮点数更高。
这对于了解PHP和按位运算也很有趣:
/**
* Regular
*/
echo (true && true); // 1
echo (true && false); // nothing
echo (true || false); // 1
echo (false || false); // nothing
echo (true xor false); // 1
echo (false xor false); // nothing
/**
* Bitwise
*/
echo (true & true); // 1
echo (true & false); // 0
echo (true | false); // 1
echo (false | false); // 0
echo (true ^ false); // 1
echo (false ^ false); // 0
echo ("cheese" & 4)
,它将输出零,而echo ("cheese" && 4)
将输出true。 - thomasrutter我知道你的问题是关于理解位运算符的,已经有一个很好的答案解释了它。但是针对你给出的例子,我不能不推荐你使用取模运算符:
($var % 2) /* instead of */ ($var & 1)
因为这样可以清晰地表明你正在检查数字是否是奇数(不可被2整除),而且它更加通用,所以你可以像使用($var % 3)一样使用它,并推导出它适用于任何N的工作原理。
除了其他答案之外,值得注意的是
if(func1() && func2())
仅在func1()
返回true时调用func2()
("惰性求值"),而
if(func1() & func2())
无论如何都会调用这两个函数,但是前提是它们返回布尔值时的真值表将相同。
thomasrutter指出(在下面的评论中)实践中可能不应该做后者。(A & B)
与(A && B)
在真值上可能并不相同,尤其当A
和B
是整数时。例如,如果A=1且B=2(都为真),则A&B将为假,而A&&B为真。此外,另一个开发人员可能会认为这是笔误并“更正”为两个和号。
func1()&& func2()
将评估为“true”,而func1()& func2()
将评估为“0”。即使在它有效的情况下,我也不会称它为良好的编码实践,因为它依赖于评估顺序和类型转换的副作用,使代码更难以阅读和理解其目的。任何审查代码的人都可能认为这是一个拼写错误。 - thomasrutter