|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2004-08-28 06:27 UTC] binhqx at mac dot com
Description: ------------ Bitwise right shift operator produces incorrect result when applied to a double in all version of PHP on OS X. During a bitwise right shift, the php processor casts the operand Reproduce code: --------------- $operand = 8726521066; echo ($operand >> 10); Expected result: ---------------- 133385 Actual result: -------------- -1 PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Nov 02 18:00:01 2025 UTC |
I did some digging in the code using gdb and found the root of the problem likly resides in zend_operators.c in shift_right_function(). On line 1108 of zend_operators.c the zendi_convert_to_long macro is called then the DVAL_TO_LVAL macro. To me, it looks like inconsistency occurs here: zend_operators.c:186 #define DVAL_TO_LVAL(d, l) (l) = (d) > LONG_MAX ? (unsigned long) (d) : (long) (d) When d is greater then LONG_MAX, d is cast as a unsigned long. When the value is then copied into op1_copy.value.lval, it is recast as to a long. The bug appears to be with the OS. Here is some code to show the inconsistency: -------------- #include <iostream> using namespace std; int main (int argc, char * const argv[]) { double large_number = 8e10; cout << "Casting Test\n"; cout << "double = " << large_number << "\n"; cout << "unsigned long = " << (unsigned long int)large_number << "\n"; cout << "long = " << (long int)(unsigned long int)large_number << "\n"; return 0; } -------------- OS X result: -------------- Casting Test double = 8e+10 unsigned long = 4294967295 long = -1 Linux result: -------------- Casting Test double = 8e+10 unsigned long = 2690588672 long = -1604378624 It looks like this is a OS X bug rather then a PHP bug. Does any one know of workaround code to make OS X act like Linux in PHP or C?