Search code examples
phpbit-manipulationbitmaskcomparison-operators

PHP bitwise operations not returning correct values


I have a function which takes a numbers and returns an array corresponding to the days (the number will be bit-masked for each day of the week). However the array is returning all the days for certain values and an empty array for another values. Below is the function

function get_days($days) {
    $days_arr = array();


echo "days: " . decbin($days) . " - type: " . gettype($days) . "<br/>";
echo "type1: " . gettype($days & 0x01) . " - type2: " . gettype(0x01) . "<br/>";
echo "days & 0x01 = " . dechex($days & 0x01) . " = " . ($days & 0x01 == 0x01) . "<br/>";
echo "days & 0x02 = " . dechex($days & 0x02) . " = " . ($days & 0x02 == 0x02) . "<br/>";
echo "days & 0x04 = " . dechex($days & 0x04) . " = " . ($days & 0x04 == 0x04) . "<br/>";
echo "days & 0x08 = " . dechex($days & 0x08) . " = " . ($days & 0x08 == 0x08) . "<br/>";
echo "days & 0x10 = " . dechex($days & 0x10) . " = " . ($days & 0x10 == 0x10) . "<br/>";


    if($days & 0x01 == 0x01)
        $days_arr[] = 'M';

    if($days & 0x02 == 0x02)
        $days_arr[] = 'T';

    if($days & 0x04 == 0x04)
        $days_arr[] = 'W';

    if($days & 0x08 == 0x08)
        $days_arr[] = 'H';

    if($days & 0x10 == 0x10)
        $days_arr[] = 'F';

    return $days_arr;
}

Below are the results of the echo

days: 10101 - type: integer
type1: integer - type2: integer
days & 0x01 = 1 = 1
days & 0x02 = 0 = 1
days & 0x04 = 4 = 1
days & 0x08 = 0 = 1
days & 0x10 = 10 = 1
days: 1010 - type: integer
type1: integer - type2: integer
days & 0x01 = 0 = 0
days & 0x02 = 2 = 0
days & 0x04 = 0 = 0
days & 0x08 = 8 = 0
days & 0x10 = 0 = 0

I can't seem to figure the reason behind the issue, it seems logical to me that this should work.


Solution

  • This is an operator precedence issue. See:

    http://php.net/manual/en/language.operators.precedence.php

    So == is above &. You should not do:

    $days & 0x02 == 0x02
    

    But:

    ($days & 0x02) == 0x02