Search code examples
phpbit-manipulationbitwise-operatorsbitwise-not

What is the effect of a double negating bitwise operator (~~) - also called "double tilde" - in PHP?


Refactoring legacy code I have found various occurrences of the following construct:

((bool) ~~$field->req ? ' required' : '')

According to the manual the Tilde (~) in PHP is the bitwise not, which simple shifts all bits in a variable to their opposite.

If I shift all bits in a variable to their opposite and then shift it back, the variable should be exactly the same as it was before right? So why would somebody do this? Am I missing something?


Solution

  • It should be !! (it converts the value to a boolean) but it is not needed at all. I guess the original coder mistaken ~ for ! then they added (bool) in front of it to achieve the desired result (because, as you noticed in the question, ~~ is a no-op).

    The ternary operator (?:) forces the evaluation of its first argument as boolean.

    The boolean value of $field->req is the same as of !! $field->req and (bool) ~~$field->req (and (bool)$field->req btw).

    I would remove the (bool) ~~ part completely to get smaller and cleaner code.

    Edit by questioner: The only effect of ~~ in PHP is to cut of decimals from a float value.

    See the following results:

    $a = 2.123;
    $b = -2.123;
    $c = new stdClass();
    $d = ["a",2,"c"];
    $e = "lord";
    $f = -3;
    $g = false;
    $h = null;
    $j = -2.99;
    $k = 2.99;
    
    
    var_dump(~~$a);
    var_dump(~~$b);
    // var_dump(~~$c); // error
    // var_dump(~~$d); // error
    var_dump(~~$e);
    var_dump(~~$f);
    // var_dump(~~$g); // error
    // var_dump(~~$h); // error
    var_dump(~~$j);
    var_dump(~~$k);
    
    var_dump(!!$a);
    var_dump(!!$b);
    var_dump(!!$c);
    var_dump(!!$d);
    var_dump(!!$e);
    var_dump(!!$f);
    var_dump(!!$g);
    var_dump(!!$h);
    var_dump(!!$j);
    var_dump(!!$k);
    

    int(2) int(-2) string(4) "lord" int(-3) int(-2) int(2) bool(true) bool(true) bool(true) bool(true) bool(true) bool(true) bool(false) bool(false) bool(true) bool(true)