NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
lib/45755: pow(0.0, negative) returns wrong value
>Number: 45755
>Category: lib
>Synopsis: pow(0.0, negative) returns wrong value
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Dec 29 06:55:00 +0000 2011
>Originator: Yui NARUSE
>Release: NetBSD 5.99.56 i386
>Organization:
>Environment:
NetBSD nbsd.rubyci.org 5.99.56 NetBSD 5.99.56 (GENERIC) #0: Sat Nov 19 01:13:35
JST 2011 root%nbsd.rubyci.org@localhost:/usr/obj/sys/arch/i386/compile/GENERIC
i386
>Description:
POSIX says "For y < 0, if x is zero, a [CX] pole error may occur and pow(),
powf(), and powl() shall return ±HUGE_VAL, ±HUGE_VALF, and ±HUGE_VALL,
respectively. [MX] On systems that support the IEC 60559 Floating-Point
option, a pole error shall occur and pow(), powf(), and powl() shall return
±HUGE_VAL, ±HUGE_VALF, and ±HUGE_VALL, respectively if y is an odd integer, or
HUGE_VAL, HUGE_VALF, and HUGE_VALL, respectively if y is not an odd integer."
http://pubs.opengroup.org/onlinepubs/9699919799/functions/pow.html
So pow(0.0, negative) should return positive infinity other than pow(-0.0,
negatieve odd) as following like IEEE754:
__ieee754_pow(0.0, -1): inf
__ieee754_pow(0.0, -2): inf
__ieee754_pow(-0.0, -1): -inf
__ieee754_pow(-0.0, -2): inf
But current implementation returns negative infinity other than pow(+0.0,
positive odd):
pow(0.0, -1): inf
pow(0.0, -2): -inf
pow(-0.0, -1): -inf
pow(-0.0, -2): -inf
>How-To-Repeat:
% cat pow.c
#include <math.h>
#include <stdio.h>
double __ieee754_pow(double x, double y);
int main(void)
{
fprintf(stderr,"LIB_VERSION: %d (POSIX: 2)\n",_LIB_VERSION);
fprintf(stderr,"pow(0.0, -1): %f\n",pow(0.0, -1));
fprintf(stderr,"pow(0.0, -2): %f\n",pow(0.0, -2));
fprintf(stderr,"pow(-0.0, -1): %f\n",pow(-0.0, -1));
fprintf(stderr,"pow(-0.0, -2): %f\n",pow(-0.0, -2));
fprintf(stderr,"__ieee754_pow(0.0, -1): %f\n",__ieee754_pow(0.0, -1));
fprintf(stderr,"__ieee754_pow(0.0, -2): %f\n",__ieee754_pow(0.0, -2));
fprintf(stderr,"__ieee754_pow(-0.0, -1): %f\n",__ieee754_pow(-0.0, -1));
fprintf(stderr,"__ieee754_pow(-0.0, -2): %f\n",__ieee754_pow(-0.0, -2));
return 0;
}
% cc -lm pow.c&&./a.out
LIB_VERSION: 2 (POSIX: 2)
pow(0.0, -1): inf
pow(0.0, -2): -inf
pow(-0.0, -1): -inf
pow(-0.0, -2): -inf
__ieee754_pow(0.0, -1): inf
__ieee754_pow(0.0, -2): inf
__ieee754_pow(-0.0, -1): -inf
__ieee754_pow(-0.0, -2): inf
>Fix:
--- lib/libm/src/k_standard.c.orig 2011-12-29 15:02:55.000000000 +0900
+++ lib/libm/src/k_standard.c 2011-12-29 15:23:45.000000000 +0900
@@ -468,8 +468,6 @@ __kernel_standard(double x, double y, in
exc.name = type < 100 ? "pow" : "powf";
if (_LIB_VERSION == _SVID_)
exc.retval = zero;
- else
- exc.retval = -HUGE_VAL;
if (_LIB_VERSION == _POSIX_)
errno = EDOM;
else if (!matherr(&exc)) {
Home |
Main Index |
Thread Index |
Old Index