Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent treatment of NaN #8036

Closed
p5pRT opened this issue Jul 26, 2005 · 11 comments
Closed

Inconsistent treatment of NaN #8036

p5pRT opened this issue Jul 26, 2005 · 11 comments

Comments

@p5pRT
Copy link

p5pRT commented Jul 26, 2005

Migrated from rt.perl.org#36654 (status was 'resolved')

Searchable as RT36654$

@p5pRT
Copy link
Author

p5pRT commented Jul 26, 2005

From @sisyphus

Created by @sisyphus

use warnings;

my $z = NaN;

$z += 1;

print $z, "\n";

__END__

When I run that I get an output of simply​:
1

NaN + 1 should be NaN, not 1. If NaN is treated as a string, then
you would expect a value of 1 - but if NaN were being treated as
a string there would have been a warning that "NaN" is not numeric -
and no such warning appears. One is left to conclude that NaN is
understood, but not handled correctly. Inf is similarly mishandled.

Same problem on both Linux and Win32.

There has been some discussion about this on the c.l.p.misc thread
called "IEEE NaN screwed up?" and the p5p thread "NaN on platforms
that don't support it".

Seems that the perlop, perlfunc, and perldata docs are also in need
of change wrt what they say about NaN.

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl v5.8.7:

Configured by Rob at Wed Jun  8 18:44:11 2005.

Summary of my perl5 (revision 5 version 8 subversion 7) configuration:
  Platform:
    osname=MSWin32, osvers=5.0, archname=MSWin32-x86-multi-thread
    uname=''
    config_args='undef'
    hint=recommended, useposix=true, d_sigaction=undef
    usethreads=define use5005threads=undef useithreads=define
usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags
='-s -O2 -DWIN32 -DHAVE_DES_FCRYPT -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_S
YS -fno-strict-aliasing -DPERL_MSVCRT_READFIX',
    optimize='-s -O2',
    cppflags='-DWIN32'
    ccversion='', gccversion='3.4.4', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='long long',
lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='g++', ldflags ='-s -L"D:\perl58_M\5.8.7\lib\CORE" -L"D:\MinGW\lib"'
    libpth=D:\MinGW\lib




libs= -lmsvcrt -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lw
inmm -lversion -lodbc32




perllibs= -lmsvcrt -lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdl
g32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr
 -lwinmm -lversion -lodbc32
    libc=-lmsvcrt, so=dll, useshrplib=yes, libperl=libperl58.a
    gnulibc_version='undef'
  Dynamic Linking:
    dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ',
lddlflags='-mdll -s -L"D:\perl58_M\5.8.7\lib\CORE" -L"D:\MinGW\lib"'

Locally applied patches:



@INC for perl v5.8.7:
    D:/perl58_M/5.8.7/lib
    D:/perl58_M/site/5.8.7/lib
    D:/perl58_M/site/lib
    .


Environment for perl v5.8.7:
    HOME (unset)
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)

PATH=D:\dmake;F:\vsnet\vc7\bin;D:\perl58_M\5.8.7\bin;D:\MinGW\bin;D:\gzip\bi
n;D:\gettext;D:\tar;D:\zip;D:\diffutils\bin;D:\bzip2\bin;D:\pgplot\bin;D:\ba
tch;C:\WINNT\system32;C:\WINNT;C:\WINNT\System32\Wbem;D:\third_party_dll;E:\
GTK\bin;;F:\WinCvs\CVSNT
    PERL_BADLANG (unset)
    SHELL (unset)




@p5pRT
Copy link
Author

p5pRT commented Aug 7, 2005

From @ysth

On Mon, Jul 25, 2005 at 05​:27​:36PM -0700, Sisyphus wrote​:

use warnings;

my $z = NaN;

$z += 1;

print $z, "\n";

__END__

When I run that I get an output of simply​:
1

NaN + 1 should be NaN, not 1. If NaN is treated as a string, then
you would expect a value of 1 - but if NaN were being treated as
a string there would have been a warning that "NaN" is not numeric -
and no such warning appears. One is left to conclude that NaN is
understood, but not handled correctly. Inf is similarly mishandled.

My impression is that we lost nan/inf handling when we switched away
from using the libc atof. This (as yet untested) should help some,
if we want to go this route​:

Inline Patch
--- perl/numeric.c.orig 2005-06-07 10:30:19.000000000 -0700
+++ perl/numeric.c      2005-08-07 10:23:55.574304000 -0700
@@ -893,6 +893,21 @@
            ++s;
     }
 
+    /* punt to strtod for NaN/Inf; if no support for it there, tough luck */
+
+#ifdef HAS_STRTOD
+    if (*s == 'n' || *s == 'N' || *s == 'i' || *s == 'I') {
+        char *p = negative ? s-1 : s;
+        char *endp;
+        NV rslt;
+        rslt = strtod(p, &endp);
+        if (endp != p) {
+            *value = rslt;
+            return (char *)endp;
+        }
+    }
+#endif
+
     /* we accumulate digits into an integer; when this becomes too
      * large, we add the total to NV and start again */
 

> Same problem on both Linux and Win32. > > There has been some discussion about this on the c\.l\.p\.misc thread > called "IEEE NaN screwed up?" and the p5p thread "NaN on platforms > that don't support it"\. > > Seems that the perlop\, perlfunc\, and perldata docs are also in need > of change wrt what they say about NaN\.

They need to not encourage barewords, at least.

@p5pRT
Copy link
Author

p5pRT commented Aug 7, 2005

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Aug 8, 2005

From @andk

On Sun, 7 Aug 2005 11​:03​:08 -0700, Yitzchak Scott-Thoennes <sthoenna@​efn.org> said​:

  > My impression is that we lost nan/inf handling when we switched away
  > from using the libc atof. This (as yet untested) should help some,
  > if we want to go this route​:

According to a binary search it was patch 10379​:

----Program----
$a = NaN; print "No NaN support here\n" if $a == $a

----Output of .../pml0oxv/perl-5.7.1@​10378/bin/perl----

----EOF ($?='0')----
----Output of .../pOqO3Kr/perl-5.7.1@​10379/bin/perl----
No NaN support here

----EOF ($?='0')----

--
andreas

@p5pRT
Copy link
Author

p5pRT commented Aug 9, 2005

From @ysth

On Sun, Aug 07, 2005 at 11​:03​:08AM -0700, Yitzchak Scott-Thoennes wrote​:

My impression is that we lost nan/inf handling when we switched away
from using the libc atof. This (as yet untested) should help some,
if we want to go this route​:

Now tested; no new failures. The more I think about it, the more this
seems like the way to go. The alternative would be a Configure probe
to determine NaN/+/-Inf bit patterns if such exist, but this would
lose special handling of NAN(n-char-sequence) style strings (if any
libc actually uses these).

The below could be improved by using strtold for long double NVs if
available, but I don't see much benefit in that.

--- perl/numeric.c.orig 2005-06-07 10​:30​:19.000000000 -0700
+++ perl/numeric.c 2005-08-07 10​:23​:55.574304000 -0700
@​@​ -893,6 +893,21 @​@​
++s;
}

+ /* punt to strtod for NaN/Inf; if no support for it there, tough luck */
+
+#ifdef HAS_STRTOD
+ if (*s == 'n' || *s == 'N' || *s == 'i' || *s == 'I') {
+ char *p = negative ? s-1 : s;
+ char *endp;
+ NV rslt;
+ rslt = strtod(p, &endp);
+ if (endp != p) {
+ *value = rslt;
+ return (char *)endp;
+ }
+ }
+#endif
+
/* we accumulate digits into an integer; when this becomes too
* large, we add the total to NV and start again */

@p5pRT
Copy link
Author

p5pRT commented Aug 11, 2005

From @ysth

On Sun, Aug 07, 2005 at 11​:03​:08AM -0700, Yitzchak Scott-Thoennes wrote​:

On Mon, Jul 25, 2005 at 05​:27​:36PM -0700, Sisyphus wrote​:

use warnings;

my $z = NaN;

$z += 1;

print $z, "\n";

__END__

When I run that I get an output of simply​:
1

NaN + 1 should be NaN, not 1. If NaN is treated as a string, then
you would expect a value of 1 - but if NaN were being treated as
a string there would have been a warning that "NaN" is not numeric -
and no such warning appears. One is left to conclude that NaN is
understood, but not handled correctly. Inf is similarly mishandled.

My impression is that we lost nan/inf handling when we switched away
from using the libc atof. This (as yet untested) should help some,
if we want to go this route​:

--- perl/numeric.c.orig 2005-06-07 10​:30​:19.000000000 -0700
+++ perl/numeric.c 2005-08-07 10​:23​:55.574304000 -0700
@​@​ -893,6 +893,21 @​@​
++s;
}

+ /* punt to strtod for NaN/Inf; if no support for it there, tough luck */
+
+#ifdef HAS_STRTOD
+ if (*s == 'n' || *s == 'N' || *s == 'i' || *s == 'I') {
+ char *p = negative ? s-1 : s;
+ char *endp;
+ NV rslt;
+ rslt = strtod(p, &endp);
+ if (endp != p) {
+ *value = rslt;
+ return (char *)endp;
+ }
+ }
+#endif
+
/* we accumulate digits into an integer; when this becomes too
* large, we add the total to NV and start again */

Same problem on both Linux and Win32.

There has been some discussion about this on the c.l.p.misc thread
called "IEEE NaN screwed up?" and the p5p thread "NaN on platforms
that don't support it".

Seems that the perlop, perlfunc, and perldata docs are also in need
of change wrt what they say about NaN.

They need to not encourage barewords, at least.

"Fixing" that part​:

Inline Patch
--- perl/pod/perlop.pod.orig    2005-07-18 02:22:07.000000000 -0700
+++ perl/pod/perlop.pod 2005-08-10 22:51:33.017411200 -0700
@@ -369,8 +369,8 @@
 returns true, as does NaN != anything else. If your platform doesn't
 support NaNs then NaN is just a string with numeric value 0.
 
-    perl -le '$a = NaN; print "No NaN support here" if $a == $a'
-    perl -le '$a = NaN; print "NaN support here" if $a != $a'
+    perl -le '$a = "NaN"; print "No NaN support here" if $a == $a'
+    perl -le '$a = "NaN"; print "NaN support here" if $a != $a'
 
 Binary "eq" returns true if the left argument is stringwise equal to
 the right argument.

@p5pRT
Copy link
Author

p5pRT commented Aug 17, 2005

From @ysth

Can the patches in​:
  http​://nntp.perl.org/group/perl.perl5.porters/103801
and
  http​://nntp.perl.org/group/perl.perl5.porters/103906

be applied (or receive feedback)? Thanks.

@p5pRT
Copy link
Author

p5pRT commented Aug 17, 2005

From @sisyphus

----- Original Message -----
From​: "Yitzchak Scott-Thoennes via RT" <perlbug-followup@​perl.org>
To​: <sisyphus1@​optusnet.com.au>
Sent​: Wednesday, August 17, 2005 2​:24 PM
Subject​: Ping? [PATCH] Re​: [perl #36654] Inconsistent treatment of NaN

Can the patches in​:
http​://nntp.perl.org/group/perl.perl5.porters/103801
and
http​://nntp.perl.org/group/perl.perl5.porters/103906

be applied (or receive feedback)? Thanks.

Hi,

Is this a question directed to me ? (If so, I don't feel qualified to
answer.)
Alternatively, perhaps this is just a CC to me (though there's nothing to
suggest that's so) of a question being asked of someone else - in which case
my reply can be ignored :-)

One thing which surprised me a little was the notion that NaN should be
assigned to a scalar as a string, rather than a bareword. My expectation was
that the *converse* would be encouraged. Since numeric values are normally
assigned as barewords, I thought that NaN and Inf would likewise be assigned
as barewords. Perhaps that's just me being weird.

Anyway - if the above-mentioned patches are going to make for better
consistency, then I have no objection to their being applied.

Cheers,
Rob

@p5pRT
Copy link
Author

p5pRT commented Aug 17, 2005

From @ysth

On Wed, Aug 17, 2005 at 04​:15​:56PM +1000, Sisyphus wrote​:

----- Original Message -----
From​: "Yitzchak Scott-Thoennes via RT" <perlbug-followup@​perl.org>
To​: <sisyphus1@​optusnet.com.au>
Sent​: Wednesday, August 17, 2005 2​:24 PM
Subject​: Ping? [PATCH] Re​: [perl #36654] Inconsistent treatment of NaN

Can the patches in​:
http​://nntp.perl.org/group/perl.perl5.porters/103801
and
http​://nntp.perl.org/group/perl.perl5.porters/103906

be applied (or receive feedback)? Thanks.

Hi,

Is this a question directed to me ? (If so, I don't feel qualified to
answer.)
Alternatively, perhaps this is just a CC to me (though there's nothing to
suggest that's so) of a question being asked of someone else - in which case
my reply can be ignored :-)

It was just a CC to you; sorry for the confusion. Bugs mostly get
discussed on the perl5-porters mailing list, and the bug tracker gets
followups from the list and files them with the bug report and
forwards them to the original reporter.

One thing which surprised me a little was the notion that NaN should be
assigned to a scalar as a string, rather than a bareword. My expectation was
that the *converse* would be encouraged. Since numeric values are normally
assigned as barewords, I thought that NaN and Inf would likewise be assigned
as barewords. Perhaps that's just me being weird.

AFAIK, NaN and Inf have never been treated as numeric constants; when
things worked before they were barewords (that is to say, strings).
Given that this provokes a fatal error under "use strict", it
shouldn't be encouraged. Going the other way and making a NaN literal
a real numeric constant that's valid under use strict would IMO raise
issues with what happens if there's a sub named NaN, and I'd rather
avoid that.

@p5pRT
Copy link
Author

p5pRT commented Aug 17, 2005

@rgs - Status changed from 'open' to 'resolved'

@p5pRT p5pRT closed this as completed Aug 17, 2005
@p5pRT
Copy link
Author

p5pRT commented Aug 17, 2005

From @rgs

Yitzchak Scott-Thoennes wrote​:

Can the patches in​:
http​://nntp.perl.org/group/perl.perl5.porters/103801
and
http​://nntp.perl.org/group/perl.perl5.porters/103906

be applied (or receive feedback)? Thanks.

Thanks, both have been applied as change #25299.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant