对布尔值的按位运算

时间:2014-09-16 18:13:52

标签: php bit-manipulation bitwise-operators

据我所知,按位运算符会检查所有相应的位,如:

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";

它给了我以下输出:

  

true和false:0
  是或否:1
  不是:0

     

true BITAND false:0
  真BITOR假:1

     

致命错误:第21行的C:\ Abyss Web Server \ htdocs \ handler.php中不支持的操作数类型

因此,我有两个问题:

  1. &&||的重点是什么,如果我们(看起来如此)可以在布尔值上使用&|
  2. 为什么我不能~true(或者换句话说,为什么不支持布尔值)?对我来说,~true返回false是合乎逻辑的。
  3. 我确实提出了一件事,因为&&||会(有时)将值转换为bool,然后返回正确的结果,如果我们(错误地)碰巧会传递一个不属于bool类型的值。但要解决这个问题,我们不能先做演员吗?如:

    if ((bool)$foo & (bool)$bar) { ...
    

    感觉我在这里错过了一件可以改变一切的重要作品...但是为了防止我没有,我尽可能多地收录信息。通过回答我的两个问题,有人能让我更好地理解这一点吗?我现在很困惑,我已经考虑了很长一段时间。

2 个答案:

答案 0 :(得分:3)

答案1

布尔表达式的部分(||&&!,...)仅在需要时(从左到右)进行评估:

  if ($a | func()) { } // func is always called
  if ($a || func()) { } // func is not called if $a is true,
                        // because expression is true whatever func will return
  if ($a && func()) { } // func is not called if $a is false,
                        // because expression is false whatever func will return
  func() || exit(); // exit() will be called if func() returns false

查看文档:{​​{3}}

答案2

~true似乎没有意义:true0x00...01~true0xff...fe而非false 0x000...0

var_dump(~((int)true)); // prints: int(-2)
echo dechex(~((int)true)); // prints: fffffffffffffffe

使用! - 运算符代替:

var_dump(!true); // prints: bool(false)

恢复

仅在需要更改位时才使用按位运算符。

答案 1 :(得分:0)

truefalse布尔标志虽然作为32位或64位值存储在内存中,但应该被视为两态布尔值。你最终只能在brach guard上使用它,所以你不应该对它们进行算术运算。 &&||计算为布尔标志,按位运算符&amp;和|评估为操作数相同(例如int & int计算为intint && int计算为布尔值。

故事是: 必须在某些条件下做出决定时,请使用&&||。使用&|对值执行布尔算术。

那是C ++

C没有任何内置布尔值,因此任何非零值都是true,零是false