NetBSD Problem Report #41931
From he@smistad.uninett.no Mon Aug 24 13:37:41 2009
Return-Path: <he@smistad.uninett.no>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
by www.NetBSD.org (Postfix) with ESMTP id 23E7A63BDF9
for <gnats-bugs@gnats.NetBSD.org>; Mon, 24 Aug 2009 13:37:41 +0000 (UTC)
Message-Id: <20090824133737.BB7A73D0A4@smistad.uninett.no>
Date: Mon, 24 Aug 2009 15:37:37 +0200 (CEST)
From: he@NetBSD.org
Reply-To: he@NetBSD.org
To: gnats-bugs@gnats.NetBSD.org
Subject: log(-INFINITY) or log(-1.0) gives uexpected results
X-Send-Pr-Version: 3.95
>Number: 41931
>Category: lib
>Synopsis: log(-INFINITY) or log(-1.0) gives uexpected results
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: lib-bug-people
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Aug 24 13:40:00 +0000 2009
>Closed-Date: Mon Apr 30 22:33:45 +0000 2012
>Last-Modified: Mon Apr 30 22:33:45 +0000 2012
>Originator: Havard Eidnes
>Release: NetBSD 5.0_RC3
>Organization:
I Try...
>Environment:
System: NetBSD smistad.uninett.no 5.0_RC3 NetBSD 5.0_RC3 (MAANEN) #4: Mon Mar 30 02:52:40 CEST 2009 he@maanen.uninett.no:/usr/obj/sys/arch/i386/compile/MAANEN i386
Architecture: i386
Machine: i386
>Description:
It appears that ANSI C specifies that log(-INFINITY) or
log(negative value) is supposed to return a NaN.
Instead, -INFINITY is returned.
>How-To-Repeat:
------------------------------
#include <math.h>
#include <stdio.h>
#include <errno.h>
/* Ref. a.o. http://www.ansic.net/showlog.php?id=31&res=log%20function */
int
main(int argc, char **argv)
{
double a, b;
a = INFINITY;
b = log(a);
printf("log(Inf) = %5f errno=%2d (expected: inf / %d)\n",
b, errno, 0);
a = -INFINITY;
b = log(a);
printf("log(-Inf) = %5f errno=%2d (expected: NaN / %d)\n",
b, errno, EDOM);
a = -1;
b = log(a);
printf("log(-1) = %5f errno=%2d (expected: NaN / %d)\n",
b, errno, EDOM);
return 0;
}
------------------------------
When run on my host, this program produces:
log(Inf) = inf errno= 0 (expected: inf / 0)
log(-Inf) = -inf errno=33 (expected: NaN / 33)
log(-1) = -inf errno=33 (expected: NaN / 33)
The same is the result when run on a sparc64/5.0 host.
I've looked at lib/libm/src/w_log.c, I think the __ieee754_log()
function is chosen, and I've looked at
lib/libm/src/e_log.c which implements that function, and
replicated the "hx/lx" extraction in my own code, and hx
definitely ends up as negative when -INFINITY is passed,
and a NaN results from the division by zero.
The comments in e_log.c even say:
* Special cases:
* log(x) is NaN with signal if x < 0 (including -INF) ;
* log(+INF) is +INF; log(0) is -INF with signal;
* log(NaN) is that NaN with no signal.
which conforms with the expected behaviour and with
section F.9.3.7 in ISO/IEC 9899 committee draft at
http://www.open-std.org/Jtc1/sc22/wg14/www/docs/n1124.pdf
My small test program:
------------------------------
#include <sys/types.h>
#include <math.h>
#include <stdio.h>
#if (BYTE_ORDER == BIG_ENDIAN) || (defined(__arm__) && !defined(__VFP_FP__))
typedef union
{
double value;
struct
{
u_int32_t msw;
u_int32_t lsw;
} parts;
} ieee_double_shape_type;
#endif
#if (BYTE_ORDER == LITTLE_ENDIAN) && \
!(defined(__arm__) && !defined(__VFP_FP__))
typedef union
{
double value;
struct
{
u_int32_t lsw;
u_int32_t msw;
} parts;
} ieee_double_shape_type;
#endif
/* Get two 32 bit ints from a double. */
#define EXTRACT_WORDS(ix0,ix1,d) \
do { \
ieee_double_shape_type ew_u; \
ew_u.value = (d); \
(ix0) = ew_u.parts.msw; \
(ix1) = ew_u.parts.lsw; \
} while (/*CONSTCOND*/0)
static const double zero = 0.0;
int
main(int argc, char **argv)
{
double a, b;
int32_t hx;
uint32_t lx;
a = -INFINITY;
printf("Decode of -INFINITY:\n");
EXTRACT_WORDS(hx, lx, a);
if (hx < 0) {
printf("hx < 0 (as expected)\n");
} else {
printf("hx >= 0 (NOT expected)\n");
}
a = -INFINITY;
b = (a-a)/zero;
printf("(-Inf - -Inf)/0.0 = %f (expected NaN)\n", b);
return 0;
}
------------------------------
which when run on my host produces
Decode of -INFINITY:
hx < 0 (as expected)
(-Inf - -Inf)/0.0 = nan (expected NaN)
(The root trigger of this problem was an attempted upgrade
of pkgsrc/lang/parrot to version 1.5.0, and a self-test tripped
over this unexpected result.)
>Fix:
Sorry, I don't know.
>Release-Note:
>Audit-Trail:
From: Havard Eidnes <he@NetBSD.org>
To: lib-bug-people@netbsd.org
Cc: gnats-bugs@netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: lib/41931: log(-INFINITY) or log(-1.0) gives uexpected results
Date: Tue, 25 Aug 2009 00:39:21 +0200 (CEST)
SGksDQoNCm1vcmUgaW5mbyBvbiB0aGlzLiAgSSB0aGluayBJJ3ZlIGNvbWUgYSBiaXQgY2xvc2Vy
IHRvIHVuZGVyc3RhbmRpbmcNCndoYXQncyBoYXBwZW5pbmcuDQoNCkFjY29yZGluZyB0byBsaWIv
bGlibS9NYWtlZmlsZSwgZm9yIG5vbi12YXggaG9zdHMsIGEgX01VTFRJX0xJQk0NCmlzIGJ1aWx0
LCBhbmQgaXQncyBvZiB0aGUgX1BPU0lYX01PREUgdmFyaWV0eS4NCg0KVGhpcyBtZWFucyB0aGF0
IGxpYi9saWJtL3NyYy93X2xvZy5jIGJ1aWxkcyB0aGUgImxvbmdlciIgdmVyc2lvbiwNCndoaWNo
IGxvb2tzIGxpa2UgdGhpczoNCg0KICAgICAgICBkb3VibGUgejsNCiAgICAgICAgeiA9IF9faWVl
ZTc1NF9sb2coeCk7DQogICAgICAgIGlmKF9MSUJfVkVSU0lPTiA9PSBfSUVFRV8gfHwgaXNuYW4o
eCkgfHwgeCA+IDAuMCkgcmV0dXJuIHo7DQogICAgICAgIGlmKHg9PTAuMCkNCiAgICAgICAgICAg
IHJldHVybiBfX2tlcm5lbF9zdGFuZGFyZCh4LHgsMTYpOyAvKiBsb2coMCkgKi8NCiAgICAgICAg
ZWxzZQ0KICAgICAgICAgICAgcmV0dXJuIF9fa2VybmVsX3N0YW5kYXJkKHgseCwxNyk7IC8qIGxv
Zyh4PDApICovDQoNCi4uLmFhbmQuLi4gX19rZXJuZWxfc3RhbmRhcmQoeCx4LDE3KSBicmluZ3Mg
dXMgdG86DQoNCiAgICAgICAgICAgIGNhc2UgMTc6DQogICAgICAgICAgICBjYXNlIDExNzoNCiAg
ICAgICAgICAgICAgICAvKiBsb2coeDwwKSAqLw0KICAgICAgICAgICAgICAgIGV4Yy50eXBlID0g
RE9NQUlOOw0KICAgICAgICAgICAgICAgIGV4Yy5uYW1lID0gdHlwZSA8IDEwMCA/ICJsb2ciIDog
ImxvZ2YiOw0KICAgICAgICAgICAgICAgIGlmIChfTElCX1ZFUlNJT04gPT0gX1NWSURfKQ0KICAg
ICAgICAgICAgICAgICAgZXhjLnJldHZhbCA9IC1IVUdFOw0KICAgICAgICAgICAgICAgIGVsc2UN
CiAgICAgICAgICAgICAgICAgIGV4Yy5yZXR2YWwgPSAtSFVHRV9WQUw7DQogICAgICAgICAgICAg
ICAgaWYgKF9MSUJfVkVSU0lPTiA9PSBfUE9TSVhfKQ0KICAgICAgICAgICAgICAgICAgZXJybm8g
PSBFRE9NOw0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFtYXRoZXJyKCZleGMpKSB7DQogICAg
ICAgICAgICAgICAgICBpZiAoX0xJQl9WRVJTSU9OID09IF9TVklEXykgew0KICAgICAgICAgICAg
ICAgICAgICAgICAgKHZvaWQpIFdSSVRFMigibG9nOiBET01BSU4gZXJyb3JcbiIsIDE4KTsNCiAg
ICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICBlcnJubyA9IEVET007DQog
ICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGJyZWFrOw0KDQphbmQgc2luY2Ugd2Un
cmUgbm90IHVzaW5nIHRoZSBfU1ZJRF8gdmFyaWFudCwgLUhVR0VfVkFMLA0KYWthLiAtSU5GSU5J
VFkgaXMgcmV0dXJuZWQuDQoNCk5vdywgSSBob25lc3RseSBkb24ndCBxdWl0ZSBrbm93IHdoaWNo
IHZhcmlhbnQgb2YgdGhlIFBPU0lYIHN0YW5kYXJkDQp0aGlzIGxpYnJhcnkgaXMgc3VwcG9zZWQg
dG8gY29uZm9ybSB0bywgYnV0Li4uDQoNCiAgaHR0cDovL3d3dy5vcGVuZ3JvdXAub3JnL29ubGlu
ZXB1YnMvOTY5OTkxOTc5OS9mdW5jdGlvbnMvbG9nLmh0bWwNCg0Kd2hpY2ggaXMgdGhlIElFRUUg
U3RkIDEwMDMuMS0yMDA4IHNwZWMgZm9yIGxvZygpLCB3aGljaCBzYXlzIHRoYXQNCnRoZSBpbnRl
bnRpb24gaXMgdG8gYmUgaWRlbnRpY2FsIHRvIElTTyBDLiAgQW55d2F5LCB0aGUgYWJvdmUNCnBh
Z2Ugc2F5czoNCg0KICAgRm9yIGZpbml0ZSB2YWx1ZXMgb2YgeCB0aGF0IGFyZSBsZXNzIHRoYW4g
MCwgW01YXSBbT3B0aW9uIFN0YXJ0XSBvcg0KICAgaWYgeCBpcyAtSW5mLCBbT3B0aW9uIEVuZF0g
YSBkb21haW4gZXJyb3Igc2hhbGwgb2NjdXIsIGFuZCBbTVhdDQogICBbT3B0aW9uIFN0YXJ0XSBl
aXRoZXIgYSBOYU4gKGlmIHN1cHBvcnRlZCksIG9yIFtPcHRpb24gRW5kXSBhbg0KICAgaW1wbGVt
ZW50YXRpb24tZGVmaW5lZCB2YWx1ZSBzaGFsbCBiZSByZXR1cm5lZC4NCg0KTm93LCBjbGVhcmx5
IHdlIGRvIHN1cHBvcnQgTmFOLg0KDQpBbmQgSVNPIEM5OSBhdA0KDQogICBodHRwOi8vd3d3Lm9w
ZW4tc3RkLm9yZy9KVEMxL1NDMjIvV0cxNC93d3cvZG9jcy9uMTI1Ni5wZGYNCg0Kc2VjdGlvbiBG
LjkuMy43IHNheXM6DQoNCiAgIGxvZyh4KSByZXR1cm5zIGEgTmFOIGFuZCByYWlzZXMgdGhlIOKA
mOKAmGludmFsaWTigJnigJkgZmxvYXRpbmctcG9pbnQNCiAgIGV4Y2VwdGlvbiBmb3IgeCA8IDAu
DQoNCmRvZXMgbm90IG9mZmVyIHRoZSBvcHRpb24gb2YgcmV0dXJuaW5nIGFuIGltcGxlbWVudGF0
aW9uLWRlZmluZWQNCnZhbHVlLg0KDQpTbyB3aHkgZG9lcyB0aGUgYWJvdmUgY29kZSByZXR1cm4g
LUlORklOSVRZIGluc3RlYWQgb2YgTmFOPw0KDQpPZiBjb3Vyc2UsIGludHJvZHVjaW5nIHRoZSBm
b2xsb3dpbmcgYml0IG9mIGNvZGUgYXQgdGhlIHN0YXJ0IG9mIHRoZQ0KcHJvZ3JhbSBmaXhlcyB0
aGUgcHJvYmxlbToNCg0KICAgICAgICBfTElCX1ZFUlNJT04gPSBfSUVFRV87DQoNCldpdGggdGhh
dCwgdGhlIHRlc3QgcHJvZ3JhbSBwcmludHMgd2hhdCdzIGV4cGVjdGVkLg0KDQpSZWdhcmRzLA0K
DQotIEhhdmFyZA0K
From: Havard Eidnes <he@NetBSD.org>
To: lib-bug-people@netbsd.org
Cc: gnats-bugs@netbsd.org, netbsd-bugs@netbsd.org
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
From: "Jukka Ruohonen" <jruoho@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/41931 CVS commit: src
Date: Sun, 10 Apr 2011 06:11:47 +0000
Module Name: src
Committed By: jruoho
Date: Sun Apr 10 06:11:47 UTC 2011
Modified Files:
src/distrib/sets/lists/tests: mi
src/tests/lib/libm: Makefile
Added Files:
src/tests/lib/libm: t_log.c
Log Message:
Add a test case for PR lib/41931 reported by he@. It was verified that these
fail on NetBSD 5.99.48 amd64 but pass on amd64 Linux (glibc 2.7).
To generate a diff of this commit:
cvs rdiff -u -r1.301 -r1.302 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r1.4 -r1.5 src/tests/lib/libm/Makefile
cvs rdiff -u -r0 -r1.1 src/tests/lib/libm/t_log.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->feedback
State-Changed-By: drochner@NetBSD.org
State-Changed-When: Mon, 11 Apr 2011 15:19:20 +0000
State-Changed-Why:
should be fixed in k_standard.c rev.1.17
From: "Matthias Drochner" <drochner@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/41931 CVS commit: src/lib/libm/src
Date: Mon, 11 Apr 2011 15:17:34 +0000
Module Name: src
Committed By: drochner
Date: Mon Apr 11 15:17:34 UTC 2011
Modified Files:
src/lib/libm/src: k_standard.c
Log Message:
let log(<0) return NaN rather than -inf in POSIX/XOPEN modes, as
requested in PR lib/41931 by Havard Eidnes (the PR refers to POSIX,
the OSF/1 manpage suggests that XOPEN should behave that way too)
being here, do the same to log10 and log2
To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/lib/libm/src/k_standard.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Jukka Ruohonen <jruohonen@iki.fi>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: PR/41931 CVS commit: src/lib/libm/src
Date: Tue, 12 Apr 2011 06:00:42 +0300
On Mon, Apr 11, 2011 at 03:20:04PM +0000, Matthias Drochner wrote:
> let log(<0) return NaN rather than -inf in POSIX/XOPEN modes, as
> requested in PR lib/41931 by Havard Eidnes (the PR refers to POSIX,
> the OSF/1 manpage suggests that XOPEN should behave that way too)
> being here, do the same to log10 and log2
Thanks for fixing this. I think we should probably audit all applicable
math(3) functions for this and other comparable issues.
From: "Jukka Ruohonen" <jruoho@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/41931 CVS commit: src/tests/lib/libm
Date: Tue, 12 Apr 2011 03:06:21 +0000
Module Name: src
Committed By: jruoho
Date: Tue Apr 12 03:06:21 UTC 2011
Modified Files:
src/tests/lib/libm: t_log.c
Log Message:
PR lib/41931 should be fixed; remove expected failure.
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/tests/lib/libm/t_log.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: feedback->closed
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Mon, 30 Apr 2012 22:33:45 +0000
State-Changed-Why:
Fixed a year ago.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.