ID: 30315 Updated by: [EMAIL PROTECTED] Reported By: tokul at users dot sourceforge dot net -Status: Open +Status: Feedback Bug Type: Variables related Operating System: Linux PHP Version: 5.0.2 New Comment:
Please try using this CVS snapshot: http://snaps.php.net/php5-STABLE-latest.tar.gz For Windows: http://snaps.php.net/win32/php5.0-win32-latest.zip Seems to be fixed, as I can't replicate it with latest snapshots (4.3/5.0/5.1). Previous Comments: ------------------------------------------------------------------------ [2004-10-05 17:58:04] php at botimer dot net According to my quick tests, there are a couple of issues at work here. They are: 1) The interpretation of hex constants 2) The conversion of numbers larger than 32-bits to 32-bit integers I whipped together this test script to figure out exactly what's happening and ran it on PHP 4.1.2 and 5.0.2. I haven't had a chance to run it on a 4.3.x, but I don't think it actually makes a difference unless it is yet another variant. The first issue is that hex constants larger than 2^31 are truncated to 2^31. I haven't thoroughly searched the documentation, but my Vim syntax highlighting suggests that 8 characters is the limit for understood hex constants. The second issue is the actual sticky point. PHP 4 exhibits the behavior I would expect. When dealing with a number larger than a 32-bit integer can hold, casting to (int) returns the low byte of the value. PHP5, however, ``makes up'' 2^31 as the value. The last four lines of output are the most interesting. On my 4.1.2 test, the values were 0, 2^31, 1, 2^31, while on 5.0.2, they were 2^31, 2^31, 2^31, 2^31. Due to the behavior of the hex constant interpretation, I would expect the 2^31 in the second and fourth lines of that section, but I would not expect PHP to ``make up'' the other two. I would classify this as a numeric bug. If PHP5 were to truncate the values, it would return as does 4.1.2. It is sensible that, because the quantity is positive, the ``rounding to the nearest positive 32-bit integer'' would yield 2^31, but I feel that it is likely undesired behavior. ====%<=====%<==== <?php $big[] = 2147483647; $big[] = 0x7FFFFFFF; $big[] = 2147483648; $big[] = 0x80000000; $big[] = 4294967295; $big[] = 0xFFFFFFFF; $big[] = 4294967296; $big[] = 0x100000000; $big[] = 4294967297; $big[] = 0x100000001; foreach ($big as $bignum) var_dump($bignum); echo "----\n"; echo (int) 4294967296 . "\n"; echo (int) 0x100000000 . "\n"; echo (int) 4294967297 . "\n"; echo (int) 0x100000001 . "\n"; ?> ====%<=====%<==== PHP 4.1.2 results: int(2147483647) int(2147483647) float(2147483648) float(2147483648) float(4294967295) float(4294967295) float(4294967296) int(2147483647) float(4294967297) int(2147483647) 0 2147483647 1 2147483647 ====%<====%<==== PHP 5.0.2 results: int(2147483647) int(2147483647) float(2147483648) float(2147483648) float(4294967295) float(4294967295) float(4294967296) int(2147483647) float(4294967297) int(2147483647) ---- 2147483647 2147483647 2147483647 2147483647 ------------------------------------------------------------------------ [2004-10-05 15:11:40] [EMAIL PROTECTED] I would argue that backwards compatibility is about making guarantees and not breaking them. It's not about simply ensuring that all behaviour remains exactly the same forever, otherwise you can't change anything at all. But no guarantee was broken in this change. ------------------------------------------------------------------------ [2004-10-05 14:48:28] [EMAIL PROTECTED] But it's still breaking backward compatibility, and that is also important. IMO this should just work like it did before. ------------------------------------------------------------------------ [2004-10-05 14:43:30] [EMAIL PROTECTED] PHP never guaranteed that integers larger than 2^31 wrap negative. It has never been true on a 64-bit platform, for example; there, your code will have always printed "3725722773". I don't think this is a PHP bug. ------------------------------------------------------------------------ [2004-10-04 10:03:43] [EMAIL PROTECTED] You didn't mention that before ;-) So no, then this is ofcourse a bug. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/30315 -- Edit this bug report at http://bugs.php.net/?id=30315&edit=1