Portal Home > Knowledgebase > Articles Database > PHP 5 xor bug


PHP 5 xor bug




Posted by liandra, 05-07-2007, 04:05 PM
PHP 5 has a really annoying bug in processing xor (^) with (-) value variable. on PHP 4 the result is : -1504876199 on PHP 5 the result is : -2147316488 Tested on 2 different PHP 5 box (debian and Fedora) I found this bug report on PHP site: http://bugs.php.net/bug.php?id=41237 but it seems they haven't resolve it yet... http://www.php.net/ChangeLog-5.php#5.2.2 the latest bugs they fixed was #41215 anybody know a workaround this bug?

Posted by tobiasly, 05-11-2007, 01:08 AM
This isn't a bug, both your answers are wrong. The problem is that, on a 32-bit machine, it is impossible to represent the number -5799680607 (your value of $a) in binary, so a true xor() can't be performed. To test this, run the following code on each machine: Each one may give you a different answer, but they're both wrong if you're on a 32 bit machine, because the correct answer is: 1111111111111111111111111111111010100110010011111110010110100001 See http://en.wikipedia.org/wiki/Twos_complement for how negative numbers are represented in binary. So, here are the "correct" representations for your values of $a, $b, and the correct result, which is -5799843495: 1111111111111111111111111111111010100110010011111110010110100001 0000000000000000000000000000000000000000000000101000110011111000 1111111111111111111111111111111010100110010011010110100101011001 If you can keep your eyeballs in line, you will see that the bottom result is correct, with each bit the xor() of the above two. And if you run your test script on a 64-bit machine, you will get the correct result. So I'm guessing they changed the way that PHP handles integers in an overflow condition, but it doesn't matter because neither is correct. So, what is it you're actually trying to achieve here? I'm guessing you're just trying to get some 3rd party code working the same between versions, instead of actually doing some sort of binary math?

Posted by liandra, 05-11-2007, 01:22 AM
decbin result : on PHP 5 : tested on 2 boxes (a Turion 64 and a Pentium 4 2.4 Ghz - 32 bit) result is : echo decbin (-5799680607) => 10000000000000000000000000000000 on PHP 4 (Tested on 32 bit machine - Intel(R) Pentium(R) 4 CPU 3.00GHz): echo decbin (-5799680607) => 10100110010011111110010110100001 your result 1111111111111111111111111111111010100110010011111110010110100001 is 64 bits The script is running fine on a PHP 4 environment, but not in PHP 5.

Posted by liandra, 05-11-2007, 01:24 AM
I tried it again on Intel(R) Xeon(TM) CPU 3.00GHz PHP 5 result is the same 1 followed by 31 zeros

Posted by tobiasly, 05-11-2007, 01:36 AM
Again, both these results are wrong. Even the PHP 4 value is wrong. It's just wrong in a different way. If you test it on a 64-bit OS, you will get the same answer I got, because that's the only correct answer. So, don't try to "fix" the problem or find a "workaround" because there is none. This will not be "fixed" in a future PHP release, and the bug report you found will not be fixed because the bug itself is invalid. The problem is that you're trying to perform an operation that your OS can't handle. You need to modify the script to test for an overflow condition and throw an error instead.

Posted by liandra, 05-11-2007, 01:59 AM
you're right, all my os is running 32 bit kernel even in the turion 64 machine. So, I guess what you're saying about how PHP 5 handle overflow is right. I'm trying to install Google Page Rank script which required some checksum calculation, and it always works in PHP 4, even though it cut the half left 32 bits.

Posted by liandra, 05-11-2007, 05:10 AM
I think I found out the solution by using GMP function. the result is correct : -5799843495

Posted by tobiasly, 05-11-2007, 11:31 AM
Great! I didn't even know about the GMP library, that's good to know for future reference.



Was this answer helpful?

Add to Favourites Add to Favourites    Print this Article Print this Article

Also Read
mchost (Views: 709)
Is RackShack.net down? (Views: 670)