Re: double val to long val conversion issue
| From: | Gustavo Lopes | Date: | Sun, 10 Feb 2013 19:27:48 +0000 |
| Subject: | Re: double val to long val conversion issue | ||
| References: | 1 2 3 4 5 6 7 8 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-65762@lists.php.net to get a copy of this message | ||
On Sun, 10 Feb 2013 16:19:46 +0100, Remi Collet <remi@fedoraproject.org> wrote:
Le 10/02/2013 15:58, Gustavo Lopes a écrit :This was I was afraid. That bug was just the tip of the iceberg. I suggest we do change the the > operator to >= like you proposed, but also that we add the fmod call. The code I gave earlier had a bug btw, as fmod can give a negative number. I changed it to this: long convert(double d) {Can you test this program on ppc64:$ gcc -O3 -lm conv.c && ./a.out 9223372036854775808 -9223372036854775808 -9223372036854775808 $ gcc -O3 -lm conv.c && ./a.out 4e21 -2943463994972700672 -1 $ gcc -O3 -lm conv.c && ./a.out 4e19 3106511852580896768 -1I get this: $ gcc -O3 -lm conv.c && ./a.out 9223372036854775808 -9223372036854775808 -9223372036854775808 $ gcc -O3 -lm conv.c && ./a.out 4e21 -2943463994972700672 0 $ gcc -O3 -lm conv.c && ./a.out 4e19 3106511852580896768 0
double dmod = fmod(d, pow(2., 64.));
if (dmod < 0) {
dmod += pow(2., 64.);
}
return (long)(unsigned long)dmod;
}
I tested the doubles around -4e21 and it worked fine:
$ ./a.out -4000000000000001048576
2943463994971652096 -9223372036854775808
$ ./a.out -4000000000000000524288
2943463994972176384 -9223372036854775808
$ ./a.out -4000000000000000000000
2943463994972700672 -9223372036854775808
$ ./a.out -3999999999999999475712
2943463994973224960 -9223372036854775808
$ ./a.out -3999999999999998951424
2943463994973749248 -9223372036854775808
In[36]:= c /@ Table[-4.*^21 + i*Ulp[-4.*^21], {i, -2, 2}]
Out[36]= {2943463994971652096, 2943463994972176384, \
2943463994972700672, 2943463994973224960, 2943463994973749248}
Any reservations?
--
Gustavo Lopes