Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:65747 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 15176 invoked from network); 10 Feb 2013 04:54:59 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 10 Feb 2013 04:54:59 -0000 Authentication-Results: pb1.pair.com header.from=smalyshev@sugarcrm.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=smalyshev@sugarcrm.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain sugarcrm.com designates 67.192.241.193 as permitted sender) X-PHP-List-Original-Sender: smalyshev@sugarcrm.com X-Host-Fingerprint: 67.192.241.193 smtp193.dfw.emailsrvr.com Linux 2.6 Received: from [67.192.241.193] ([67.192.241.193:52949] helo=smtp193.dfw.emailsrvr.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 37/52-02995-02827115 for ; Sat, 09 Feb 2013 23:54:58 -0500 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp9.relay.dfw1a.emailsrvr.com (SMTP Server) with ESMTP id DAE393C01E5; Sat, 9 Feb 2013 23:54:53 -0500 (EST) X-Virus-Scanned: OK Received: by smtp9.relay.dfw1a.emailsrvr.com (Authenticated sender: smalyshev-AT-sugarcrm.com) with ESMTPSA id D8E183C014E; Sat, 9 Feb 2013 23:54:50 -0500 (EST) Message-ID: <51172819.4000806@sugarcrm.com> Date: Sat, 09 Feb 2013 20:54:49 -0800 Organization: SugarCRM User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:17.0) Gecko/20130107 Thunderbird/17.0.2 MIME-Version: 1.0 To: Remi Collet CC: PHP Internals References: <511666DE.8080809@fedoraproject.org> In-Reply-To: <511666DE.8080809@fedoraproject.org> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] double val to long val conversion issue From: smalyshev@sugarcrm.com (Stas Malyshev) 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