Hi! > About > http://git.php.net/?p=php-src.git;a=commitdiff;h=79956330fe17cfd5f60de456497541b21a89bddf > (For now, I have reverted this fix) > > Here some explanations. > > LONG_MAX is 9223372036854775807 (0x7fffffffffffffff) > double representation of LONG_MAX is 9223372036854775808
I see what's going on here. We have precision loss due to the fact that the range of double (53 bits) is smaller than the range of long (63 bits) on 64-bit system. When it's converted back to long, I guess it has to be expanded back to 63 bits. > 9223372036854775807 on ppc64 > 9223372036854775808 on x86_64 (gcc without optimization) > 9223372036854775807 on x86_64 (gcc -O2) > > PHP expected value is 9223372036854775808 Not sure how value of long can be expected to be 9223372036854775808 - 9223372036854775808 is not representable in signed long. If you do (long)(unsigned long), you'd get -9223372036854775808. > (Btw, I don't understand why PHP, build on x86_64, with -O2, gives the > good result, some environment mystery) With -O2, gcc probably pre-calculates the result of the operation if you use simple test program. So, if I write: double b = LONG_MAX; printf("%ld", (long)b); Then without -O2, I'm getting: movsd -16(%rbp), %xmm0 cvttsd2siq %xmm0, %rsi But with -O2, it's just: movabsq $9223372036854775807, %rsi So the difference in results may stem from the fact that the calculations go in different way here. > Obviously, we could have different result on different platform, > compiler, architecture. > > I will be very interested by result on other platform (mac, windows), > compiler (Visual C), architecture. > > If we switch to the unsigned cast: > (long)(unsigned long)d; > > The result is always 9223372036854775808 (which is expected) Wait, long can not be 9223372036854775808, how the result of long conversion can be that? > From my tests, this doesn't change anything on x86_64, and improves Well, for the value of (double)LONG_MAX the code actually changes substantially, and if I test this code: double b = LONG_MAX; printf("%ld %ld", (long)(unsigned long)b, (long)b); Then with -O2 I get different results: -9223372036854775808 9223372036854775807 But that may be an optimization artifact. With real PHP, the result of converting 9223372036854775807 to double and then back to int seems to always be -9223372036854775808 on Intel, with or without the patch. I don't have access to ppc64 machine so no idea what's going on there. -- Stanislav Malyshev, Software Architect SugarCRM: http://www.sugarcrm.com/ (408)454-6900 ext. 227 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php