I found a problem while trying to do some bitwise operations (e.g. 32 bits XOR) in PHP. Consider the following case:
$a = -3036738507; // stored in float type
$b = 98758; // stored in integer type
$c= ($a & 0xFFFFFFFF) ^ $b;
Note: In PHP, if you specify a number beyond the bounds of the integer type, it will be interpreted as a float instead.
When I run the code in Windows, it gives me the correct value: $c = 1258196467
. But when I run the code in Linux, it gives me the incorrect value: $c = -2147384890
(it seems like an integer overflow).
4AFF0C35 ^ 181C6 = 4AFE8DF3
Is this a bug in PHP? I tried shift bits and type casting, it doesn’t give me the corrent answers in Linux.
$t1 = ($a>>24) & 0xFF; $t2 = ($a>>16) & 0xFF; $t1 = ($a>>8) & 0xFF; $t1 = ($a>>0) & 0xFF;
$a = ($t1< <24) | ($t2<<16) | ($t3<<8) | ($t4<<0);
$c= $a ^ $b;
and
$c= ((int)$a) ^ $b;
Anyway, I have a quick solution for it:
function cvt32($a) {
$maxInt = (float)(0xFFFFFFFF +1);
$temp = round ($a / $maxInt);
$out = $a - $temp * $maxInt;
return (int) $out;
}
$a = -3036738507; // stored in float type
$b = 98758; // stored in integer type
$c= cvt32($a) ^ $b;
The function cvt32()
above takes 32 bits (least significant bits) from the float
and return it as a integer
so that PHP can do 32 bits bitwise operation correctly.
EngLee says
You seem like enjoy programming too much!