NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: lib/41931: log(-INFINITY) or log(-1.0) gives uexpected results



The following reply was made to PR lib/41931; it has been noted by GNATS.

From: Havard Eidnes <he%NetBSD.org@localhost>
To: lib-bug-people%netbsd.org@localhost
Cc: gnats-bugs%netbsd.org@localhost, netbsd-bugs%netbsd.org@localhost
Subject: Re: lib/41931: log(-INFINITY) or log(-1.0) gives uexpected results
Date: Tue, 25 Aug 2009 00:54:56 +0200 (CEST)

 [[ re-send with the utf-8 replaced by ascii, so perhaps we avoid
    base64-encoding the message... ]]
 
 Hi,
 
 more info on this.  I think I've come a bit closer to understanding
 what's happening.
 
 According to lib/libm/Makefile, for non-vax hosts, a _MULTI_LIBM
 is built, and it's of the _POSIX_MODE variety.
 
 This means that lib/libm/src/w_log.c builds the "longer" version,
 which looks like this:
 
         double z;
         z = __ieee754_log(x);
         if(_LIB_VERSION == _IEEE_ || isnan(x) || x > 0.0) return z;
         if(x==0.0)
             return __kernel_standard(x,x,16); /* log(0) */
         else
             return __kernel_standard(x,x,17); /* log(x<0) */
 
 ...aand... __kernel_standard(x,x,17) brings us to:
 
             case 17:
             case 117:
                 /* log(x<0) */
                 exc.type = DOMAIN;
                 exc.name = type < 100 ? "log" : "logf";
                 if (_LIB_VERSION == _SVID_)
                   exc.retval = -HUGE;
                 else
                   exc.retval = -HUGE_VAL;
                 if (_LIB_VERSION == _POSIX_)
                   errno = EDOM;
                 else if (!matherr(&exc)) {
                   if (_LIB_VERSION == _SVID_) {
                         (void) WRITE2("log: DOMAIN error\n", 18);
                       }
                   errno = EDOM;
                 }
                 break;
 
 and since we're not using the _SVID_ variant, -HUGE_VAL,
 aka. -INFINITY is returned.
 
 Now, I honestly don't quite know which variant of the POSIX standard
 this library is supposed to conform to, but...
 
   http://www.opengroup.org/onlinepubs/9699919799/functions/log.html
 
 which is the IEEE Std 1003.1-2008 spec for log(), which says that
 the intention is to be identical to ISO C.  Anyway, the above
 page says:
 
    For finite values of x that are less than 0, [MX] [Option Start] or
    if x is -Inf, [Option End] a domain error shall occur, and [MX]
    [Option Start] either a NaN (if supported), or [Option End] an
    implementation-defined value shall be returned.
 
 Now, clearly we do support NaN.
 
 And ISO C99 at
 
    http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
 
 section F.9.3.7 says:
 
    log(x) returns a NaN and raises the "invalid" floating-point
    exception for x < 0.
 
 does not offer the option of returning an implementation-defined
 value.
 
 So why does the above code return -INFINITY instead of NaN?
 
 Of course, introducing the following bit of code at the start of the
 program fixes the problem:
 
         _LIB_VERSION = _IEEE_;
 
 With that, the test program prints what's expected.
 
 Regards,
 
 - Havard
 


Home | Main Index | Thread Index | Old Index