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



[[ 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