Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bitwise operations on boolean values

From my knowledge, bitwise operators perform a check on all corresponding bits, as in:

echo 64 | 32;   //prints 96
echo 'a' & 'b'; //prints `

While conditional && and || operators perform operations on boolean values:

echo (int)(true && false); //prints: 0
echo (int)(true || false); //prints: 1

When I (in my head) want to predict the result of a bitwise operation, I first convert the values into their binary representation (which depends on the datatype). After this, I compare it bit-for-bit, and convert the result into the suitable output type (which I suppose is determined by the operands). Although at one point, I tried doing the same with boolean values, which (from my knowledge) only consists of one bit in memory, making true corresponding to 1₂, and making false corresponding to 0₂ (in binary). Performing bitwise operations on these values should therefore produce a similar result as with && and ||, right? To show you what I mean:

true & false    =>      1₂ & 0₂      =>      0₂     =>     false
true | false    =>      1₂ | 0₂      =>      1₂     =>     true
~true           =>      ~1₂          =>      0₂     =>     false

(Not including xor, as there's no corresponding conditional boolean operator.)

To me, it looks like the behaviour should be really equivalent to conditional operators:

true && false   =>      false
true || false   =>      true
!true           =>      false

So therefore, I set this code up to test it:

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

It gave me the following output:

true AND false: 0
true OR false: 1
NOT true: 0

true BITAND false: 0
true BITOR false: 1

Fatal error: Unsupported operand types in C:\Abyss Web Server\htdocs\handler.php on line 21

So from this, I have two questions:

  1. What's the point with && and ||, if we (as it seems) can use & and | on boolean values instead?
  2. Why can't I do ~true (or with other words, why aren't boolean values supported)? To me, it sounds logical that ~true returns false.

I did come up with one thing, being that && and || will (sometimes) cast the values into bool and thereafter return the correct results, if we (by mistake) would happen to pass a value that's not of type bool. But to solve that, can't we just do a cast first? Such as:

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

It feels like I'm missing a major piece here that changes everything... But just in case I didn't, I included as much info as I could. Could someone make me understand this a bit better, by answering my two questions? I'm pretty confused at this point, and I've been thinking about this for quite some time.

like image 919
Max Avatar asked Oct 20 '25 10:10

Max


1 Answers

Answer 1

Parts of a boolean expressions (||, &&, !, ...) are only evaluated if needed (from left to right):

  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

Take a look at the documentation: http://php.net/manual/en/language.operators.logical.php

Answer 2

~true seems not to be meaningful: true is 0x00...01 and ~true will be 0xff...fe and not false 0x000...0:

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

Use !-operator instead:

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

Résumé

Use bitwise operators only if you need to change bits.

like image 102
R1tschY Avatar answered Oct 21 '25 22:10

R1tschY