
tchrist at perl
May 22, 2008, 11:46 AM
Post #6 of 7
(127 views)
Permalink
|
|
Re: [perl #54590] "Can't take log of 0" error in perl 5.8.8. 64 bit
[In reply to]
|
|
Scripsit hodie, XI Kalendas Iunias MMDCCLXI AUC, circa horam quartam mediamque post meridiem (tempus Romae), Abigail <abigail[at]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
|