Re: double val to long val conversion issue

From: 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 :
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 -1
I 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
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) {
    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

« previous php.internals (#65762) next »