develooper Front page | perl.perl5.porters | Postings from August 2003

all 9007199254740992s are equal, but some are more equal than others

Thread Next
From:
Nicholas Clark
Date:
August 27, 2003 13:10
Subject:
all 9007199254740992s are equal, but some are more equal than others
Message ID:
20030827211002.B558@plum.flirble.org
I do not understand *how* the following session can happen. But it did.
What am I missing?

(gdb) run  -le ' $b = 9007199254740992; print int $b'
Starting program: /home/nick/perl-5.8.0-g-noDEB/./perl -le ' $b = 9007199254740992; print int $b'

Breakpoint 1, Perl_pp_int () at pp.c:2770
2770        dSP; dTARGET; tryAMAGICun(int);
(gdb) next
2773          IV iv = TOPi; /* attempt to convert to IV if possible. */
(gdb) 
2779          if (SvIOK(TOPs)) {
(gdb) 
2786              value = TOPn;
(gdb) 
2787              if (value >= 0.0) {
(gdb) 
2788                  if (value < (NV)UV_MAX + 0.5) {
(gdb) 
2806                      double tmp = (double)value;
(gdb) 
2807                      (void)Perl_modf(tmp, &tmp);
(gdb) print tmp
$15 = 9007199254740992
(gdb) print tmp-9007199254740992
$16 = 0
(gdb) next
2808                      value = (NV)tmp;
(gdb) print tmp
$17 = 9007199254740992
(gdb) print tmp-9007199254740992
$18 = 0
(gdb) cont
Continuing.
9.00719925474099e+15

Program exited normally.
(gdb) run  -le ' $b = 2**53; print int $b'
Starting program: /home/nick/perl-5.8.0-g-noDEB/./perl -le ' $b = 2**53; print int $b'

Breakpoint 1, Perl_pp_int () at pp.c:2770
2770        dSP; dTARGET; tryAMAGICun(int);
(gdb) next
2773          IV iv = TOPi; /* attempt to convert to IV if possible. */
(gdb) 
2779          if (SvIOK(TOPs)) {
(gdb) 
2786              value = TOPn;
(gdb) 
2787              if (value >= 0.0) {
(gdb) 
2788                  if (value < (NV)UV_MAX + 0.5) {
(gdb) 
2806                      double tmp = (double)value;
(gdb) 
2807                      (void)Perl_modf(tmp, &tmp);
(gdb) print tmp
$19 = 9007199254740992
(gdb) print tmp-9007199254740992
$20 = 0
(gdb) next
2808                      value = (NV)tmp;
(gdb) print tmp
$21 = 1
(gdb) print tmp-9007199254740992
$22 = -9007199254740991
(gdb) print $15-$19
$23 = 0

The important part is that just before the call to modf the values are
equal, and yet the modf produces different results. It's not even the
conversion back to the perl SV that is at fault - the modf produces
different results for the (seemingly) identical input.

Nicholas Clark

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About