Re: double val to long val conversion issue
| From: | Gustavo Lopes | Date: | Wed, 20 Feb 2013 09:44:11 +0000 |
| Subject: | Re: double val to long val conversion issue | ||
| References: | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-66039@lists.php.net to get a copy of this message | ||
Em 2013-02-20 9:15, Stas Malyshev escreveu:
Hi!It doesn't, of course. I was just showing why there are changes in sign.I'm not sure I understand, what this syntax means and how it explains why we're doing these conversions?Also, I'm not sure I understand what 64-bit test is supposed to return and why - why negative number is converted to positive one? What exactly this change is supposed to improve?The least significant bytes are preserved. Take int(-2056257536) and int(2943463994971652096): In[6]:= BitAnd[2^32 - 1, {-2056257536, 2943463994971652096}] Out[6]= {2238709760, 2238709760}
I.e. what requires this change and how it is beneficial? I understand that it preserves least significant bits, but why we should preserve them and discard sign, for example?First of all, there are no change for the ]LONG_MAX, ULONG_MAX] range. Doubles in that range (notice they're positive numbers) already got converted to negative numbers. The problem was that for numbers outside the [LONG_MIN, ULONG_MAX] range, the code relied on undefined behavior that did vary between platforms. This change does away with the undefined behavior and provides a uniform treatment of the finite double domain. (int)$dval is now round*($dval) mod 2^(PHP_INT_SIZE*8) converted to a signed integer of size PHP_INT_SIZE*8 bits assuming a two's complement representation, for all finite $dval double values. You could argue that another behavior like clipping at LONG_MAX/LONG_MIN is preferable. But we can't do it for BC reasons. And especially for 32-bit long systems, the current behavior is very useful. For instance let's say you had some network protocol that used an unsigned 32-bit int on which you needed to do some bitwise operations. You can use a double to represent the range 2^31..2^32-1 that you got from, from instance, adding two large PHP integers, cast it to int and do your bitwise operation. * Actually, I just realized the code probably needs a small adjustment to make the double always round towards zero. This is only important in 32-bit systems though; for the others, the doubles outside the long range have no fractional part. -- Gustavo Lopes