【发布时间】:2014-09-16 18:13:51
【问题描述】:
据我所知,按位运算符会检查所有相应的位,如下所示:
echo 64 | 32; //prints 96
echo 'a' & 'b'; //prints `
虽然条件 && 和 || 运算符对布尔值执行操作:
echo (int)(true && false); //prints: 0
echo (int)(true || false); //prints: 1
当我(在我的脑海中)想要预测按位运算的结果时,我首先将值转换为它们的二进制表示形式(这取决于数据类型)。在此之后,我逐位比较它,并将结果转换为合适的输出类型(我想这是由操作数决定的)。虽然在某一时刻,我尝试对布尔值做同样的事情,它(据我所知)只包含内存中的一位,使true对应于1₂,并使false对应于0₂(在二进制)。因此,对这些值执行按位运算应该会产生与&& 和|| 类似的结果,对吧?向您展示我的意思:
true & false => 1₂ & 0₂ => 0₂ => false
true | false => 1₂ | 0₂ => 1₂ => true
~true => ~1₂ => 0₂ => false
(不包括xor,因为没有对应的条件布尔运算符。)
在我看来,这种行为应该真的等同于条件运算符:
true && false => false
true || false => true
!true => false
因此,我设置了这段代码来测试它:
echo "true AND false: " . ((true && false) ? "1" : "0") . "<br />\n";
echo "true OR false: " . ((true || false) ? "1" : "0") . "<br />\n";
echo "NOT true: " . ((!true) ? "1" : "0") . "<br />\n";
echo "<br />\n";
echo "true BITAND false: " . ((true & false) ? "1" : "0") . "<br />\n";
echo "true BITOR false: " . ((true | false) ? "1" : "0") . "<br />\n";
echo "BITNOT true: " . ((~true) ? "1" : "0") . "<br />\n";
它给了我以下输出:
真假:0
真或假:1
不正确:0真 BITAND 假:0
真比特假:1致命错误:第 21 行的 C:\Abyss Web Server\htdocs\handler.php 中不支持的操作数类型
因此,我有两个问题:
- 如果我们(看起来)可以在布尔值上使用
&和|,那么&&和||有什么意义? - 为什么我不能
~true(或者换句话说,为什么不支持布尔值)?对我来说,~true返回false听起来合乎逻辑。
我确实想出了一件事,那就是 && 和 || 将(有时)将值转换为 bool,然后返回正确的结果,如果我们(错误地)碰巧传递了一个值那不是bool 的类型。但是要解决这个问题,我们不能先做一个演员表吗?如:
if ((bool)$foo & (bool)$bar) { ...
感觉就像我在这里错过了一个改变一切的重要部分......但以防万一我没有,我尽可能多地提供信息。有人可以通过回答我的两个问题让我更好地理解这一点吗?在这一点上我很困惑,我已经考虑了很长时间。
【问题讨论】:
-
位运算符不返回布尔值,除非它们对布尔值进行运算,比较运算符总是返回布尔结果......这是一个非常重要的区别
-
两个整数值的位运算符将返回一个整数值...例如(使用 8 位简化)
00001000|00000111将返回00001111;00001111&01010101将返回00000101 -
@Mark Baker 确实如此,尽管这就是为什么我假设在某处显式强制转换是合适的(就像在我的上一个示例中一样)。我的意思是,如果条件运算符(或比较运算符)有 2 个不同的值,他们需要先转换它们,对吗?那么无论运营商如何,都不会进行演员阵容吗?或者我提供的最后一个代码还有其他弱点吗? (换句话说,
8和7不是这样转换的:(bool)8 | (bool)7,即使我们使用8 || 7?) -
当 PHP 将对布尔值进行隐式强制转换时,为什么会有显式强制转换的开销......并且一旦值为布尔值,比较可能比按位运算更快
-
嗯 PHP 是开源的,所以你可以随时查看源代码......但是这两种类型的运算符是为非常不同的目的而设计的......按位运算符适用于布尔值,但它们的力量正在处理非布尔值......并且因为 PHP 是松散类型的,比较运算符旨在处理任何数据类型......并且两种类型的运算符的行为都有很好的记录
标签: php bit-manipulation bitwise-operators