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

**To**:**lib-bug-people%netbsd.org@localhost,gnats-admin%netbsd.org@localhost,netbsd-bugs%netbsd.org@localhost,he%NetBSD.org@localhost****Subject**:**Re: lib/41931: log(-INFINITY) or log(-1.0) gives uexpected results****From**:**Havard Eidnes <he%NetBSD.org@localhost>**- Date: Mon, 24 Aug 2009 22:55:03 +0000 (UTC)

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

- Prev by Date:
**Re: lib/41931: log(-INFINITY) or log(-1.0) gives uexpected results** - Next by Date:
**kern/41935: Addition to umass(4) man-page** - Previous by Thread:
**Re: lib/41931: log(-INFINITY) or log(-1.0) gives uexpected results** - Next by Thread:
**port-i386/41932: bootloader should explicitly warn failure of loading modules** - Indexes: