Front page | perl.perl5.porters |
Postings from May 2008
Re: [perl #54590] "Can't take log of 0" error in perl 5.8.8. 64 bit
From:
Tom Christiansen
Date:
May 22, 2008 11:46
Subject:
Re: [perl #54590] "Can't take log of 0" error in perl 5.8.8. 64 bit
Message ID:
29721.1211481961@chthon
Scripsit hodie, XI Kalendas Iunias MMDCCLXI AUC, circa horam quartam
mediamque post meridiem (tempus Romae), Abigail <abigail@abigail.be>:
> On Wed, May 21, 2008 at 10:14:48AM -0700, Lourdes Peña Castillo wrote:
>> # New Ticket Created by "Lourdes Peña Castillo"
>> # Please include the string: [perl #54590]
>> # in the subject line of all future correspondence about this issue.
>> # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=3D54590 >
>> Hi,
>> If I run the following code in perl v5.8.8 built for x86_64-linux-
>> thread-multi, I get the error "Can't take log of 0 at - line 1."
>> perl
>> print log(2.5e-310)/log(10);
>> But if I run it in perl v5.8.7 built for i486-linux-gnu-thread-multi,
>> I get
>> Is this a known issue with perl 5.8.8. for 64bits? Thanks!
[... now enter Abigail ...]
> I see a difference depending on whether Perl was build using 64 bit
> integers or not, I get the error when running with 32 bit build, and
> -309.602059991327962 when running with a 64 bit build. The version
> (5.8.7, 5.8.8, 5.10.0) doesn't matter, nor does it matter whether it
> was built with threads or not.
> It seems that in a 32-bit build, 2.5e-310 gets constant folded to 0.
Abigail and Lourdes,
I get slightly mixed results depending on version, configuration, and
platform (software+hardware). Here're the five different boxes and the
respective perl versions I tested under each box. Amongst perl5 tests,
I see the log 0 failure occurring uniquely on the last of these alone:
Box vperl details
A v5.8.8 cygwin-thread-multi-64int
B v5.6.0 i686-linux-thread
v5.10.0 i686-linux-thread-multi-64int
C 5.005_02 OpenBSD.i386-openbsd
5.005_03 OpenBSD.i386-openbsd
5.005_54 OpenBSD.i386-openbsd
v5.6.0 OpenBSD.i386-openbsd-thread
v5.8.7 OpenBSD.i386-openbsd
v5.10.0 0penBSD.i386-openbsd-thread-multi-64int
D v5.8.8 OpenBSD.i386-openbsd
v5.10.0 OpenBSD.i386-openbsd
E v5.6.0 OpenBSD.sparc-openbsd
v5.10.0 OpenBSD.sparc-openbsd <- Can't take log of 0
On all of these EXCEPT FOR THE VERY LAST-MOST ENTRY ALONE,
I universally get
-309.602059991328
Although admittedly when on machine C, I run
boxC% perl1 -e 'print log(2.5e-310)/log(10), "\n";'
-309.60205999132796251
or
boxC% perl4.036 -e 'print log(2.5e-310)/log(10), "\n";'
-309.60205999132796251
I do get more digits. But they're there anyway, since
boxC% perl5.10.0 -e 'printf "%.45f\n", log ( 2.5e-310 ) /log ( 10 ) '
-309.602059991327962507057236507534980773925781250
No, the different response of not being able to take the log of 0 occurs
only on that fifth machine, the sparc, *but* it occurs only with 5.10.0,
*not* 5.6.0--and, somewhat curiously, it is a run-time exception, too:
boxE% perl5.6.0 -le 'print log ( 2.5e-310 ) /log( 10 ) '
-309.60205999132796251
boxE% perl5.10.0 -le 'print log ( 2.5e-310 ) /log( 10 ) '
Can't take log of 0 at -e line 1.
Exit 255
boxE% perl5.10.0 -cw -le 'print log ( 2.5e-310 ) /log( 10 ) '
-e syntax OK
Whereas in older Perl, it was usually a compile-time error.
We can use 1/0 to show that this was always the case until
the lastmost release; that is, up until 5.10.0.
Although I see that it runs just fine under original perl,
(ie, perl1) which had the curious behaviour of producing
an Inf--and exiting 0! (O *how* I do so *love* venerably
retrotesting code with perl1! :-)
boxC% perl1 -e 'print 1/0, "\n";'
Inf
But later than that, we get an exception during compilation
due to constant-folding:
boxC% perl4.036 -cw -le 'print 1/0'
Illegal division by constant zero in file /tmp/perl-eY11150 at line 2, next char ;
/tmp/perl-eY11150 had compilation errors.
Exit 2
boxC% perl5.00503 -cw -le 'print 1/0'
Illegal division by zero at -e line 1.
Exit 255
boxC% perl5.8.7 -cw -le 'print 1/0'
Illegal division by zero at -e line 1.
Exit 255
Yet today, this is different--depending. Whatever happened to
constant-folding at compile-time? Oh right! No exceptions there
any longer; I'd forgotten that particular delta entry.
boxC% perl5.10.0 -cw -le 'print 1/0'
-e syntax OK
boxC% perl5.10.0 -le 'print 1/0'
Illegal division by zero at -e line 1.
Exit 19
Curious range of exit status, though, eh? 19? Why 19?
That seems to make no sense as a sysexit, a signo, nor
an errno--yet I should presume it but a malinging errno,
though; wouldn't you?
It's certainly not a sysexit per sysexit.h at all (they're >64),
which, rather lamentably, nobody much uses. See <sysexit.h>:
EX_OK EX_CANTCREAT EX_CONFIG EX_DATAERR EX_IOERR EX_NOHOST
EX_NOINPUT EX_NOPERM EX_NOUSER EX_OSERR EX_OSFILE EX_PROTOCOL
EX_SOFTWARE EX_TEMPFAIL EX_UNAVAILABLE EX_USAGE
Now, if it were 128..255, that then I thiknk would be a signal in
the high byte. And signal 19 is SIGCONT, the now-unused SIGFPE,
only 8. But it's not, so I think it an errno. Don't you?
Digging through docs on die() to figure out what happened suggests
die() seems to have taken some errno that was just sitting around
and used that. But errno 19 is ENODEV.
The CRT (=libc startup) often leaves this value lying about, perhaps
from a failed isatty(3). *But* when it leaves the errno lying about,
*you* end up lying about what was lying about; that is, about what
really occurrred, so to speak. :-)
Now I ask you, is this behaviour all of: reasonable and expected,
understandable and predictable, *and* desirable?
FTR, my own current answer to that question happens to be "hmm".
--tom