This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Hi! ISO C99 explicitely requires that: ilogb(0) returns FP_ILOGB0 where FP_ILOGB0 is either INT_MIN, or -INT_MAX. ilogb(NaN) returns FP_ILOGBNAN where FP_ILOGBNAN is either INT_MIN or INT_MAX. ilogb(+-Inf) returns INT_MAX. so we return wrong results on i386 for infinity where FP_ILOGBNAN is INT_MIN. The following patch makes sure ilogb(+-Inf) returns INT_MAX (the non-assembly changes are actually not required, but are there for completeness and are optimized out). 2001-06-04 Jakub Jelinek <jakub@redhat.com> * math/libm-test.inc (ilogb_test): Test that ilogb(+-Inf) == INT_MAX. * sysdeps/i386/fpu/s_ilogb.S (__ilogb): Return INT_MAX for +-Inf. * sysdeps/i386/fpu/s_ilogbf.S (__ilogbf): Likewise. * sysdeps/i386/fpu/s_ilogbl.S (__ilogbl): Likewise. * sysdeps/ieee754/dbl-64/s_ilogb.c (__ilogb): Likewise. * sysdeps/ieee754/flt-32/s_ilogbf.c (__ilogbf): Likewise. * sysdeps/ieee754/ldbl-128/s_ilogbl.c (__ilogbl): Likewise. * sysdeps/ieee754/ldbl-96/s_ilogbl.c (__ilogbl): Likewise. --- libc/math/libm-test.inc.jj Mon Jun 4 10:01:59 2001 +++ libc/math/libm-test.inc Mon Jun 4 12:54:26 2001 @@ -120,6 +120,7 @@ #include <math.h> #include <float.h> #include <fenv.h> +#include <limits.h> #include <errno.h> #include <stdlib.h> @@ -2800,6 +2801,8 @@ ilogb_test (void) TEST_f_i (ilogb, 0.0, FP_ILOGB0, EXCEPTIONS_OK); TEST_f_i (ilogb, nan_value, FP_ILOGBNAN, EXCEPTIONS_OK); + TEST_f_i (ilogb, plus_infty, INT_MAX, EXCEPTIONS_OK); + TEST_f_i (ilogb, minus_infty, INT_MAX, EXCEPTIONS_OK); END (ilogb); } --- libc/sysdeps/i386/fpu/s_ilogb.S.jj Wed Jul 14 01:34:41 1999 +++ libc/sysdeps/i386/fpu/s_ilogb.S Mon Jun 4 12:48:24 2001 @@ -9,6 +9,16 @@ RCSID("$NetBSD: s_ilogb.S,v 1.5 1995/10/ ENTRY(__ilogb) fldl 4(%esp) +/* I added the following ugly construct because ilogb(+-Inf) is + required to return INT_MAX in ISO C99. + -- jakub@redhat.com. */ + fxam /* Is NaN or +-Inf? */ + fstsw %ax + movb $0x45, %dh + andb %ah, %dh + cmpb $0x05, %dh + je 1f /* Is +-Inf, jump. */ + fxtract pushl %eax fstp %st @@ -17,6 +27,10 @@ ENTRY(__ilogb) fwait popl %eax + ret + +1: fstp %st + movl $0x7fffffff, %eax ret END (__ilogb) weak_alias (__ilogb, ilogb) --- libc/sysdeps/i386/fpu/s_ilogbl.S.jj Wed Jul 14 01:34:48 1999 +++ libc/sysdeps/i386/fpu/s_ilogbl.S Mon Jun 4 12:50:35 2001 @@ -10,6 +10,16 @@ RCSID("$NetBSD: $") ENTRY(__ilogbl) fldt 4(%esp) +/* I added the following ugly construct because ilogb(+-Inf) is + required to return INT_MAX in ISO C99. + -- jakub@redhat.com. */ + fxam /* Is NaN or +-Inf? */ + fstsw %ax + movb $0x45, %dh + andb %ah, %dh + cmpb $0x05, %dh + je 1f /* Is +-Inf, jump. */ + fxtract pushl %eax fstp %st @@ -18,6 +28,10 @@ ENTRY(__ilogbl) fwait popl %eax + ret + +1: fstp %st + movl $0x7fffffff, %eax ret END (__ilogbl) weak_alias (__ilogbl, ilogbl) --- libc/sysdeps/i386/fpu/s_ilogbf.S.jj Wed Jul 14 01:34:45 1999 +++ libc/sysdeps/i386/fpu/s_ilogbf.S Mon Jun 4 12:50:27 2001 @@ -9,6 +9,16 @@ RCSID("$NetBSD: s_ilogbf.S,v 1.4 1995/10 ENTRY(__ilogbf) flds 4(%esp) +/* I added the following ugly construct because ilogb(+-Inf) is + required to return INT_MAX in ISO C99. + -- jakub@redhat.com. */ + fxam /* Is NaN or +-Inf? */ + fstsw %ax + movb $0x45, %dh + andb %ah, %dh + cmpb $0x05, %dh + je 1f /* Is +-Inf, jump. */ + fxtract pushl %eax fstp %st @@ -17,6 +27,10 @@ ENTRY(__ilogbf) fwait popl %eax + ret + +1: fstp %st + movl $0x7fffffff, %eax ret END (__ilogbf) weak_alias (__ilogbf, ilogbf) --- libc/sysdeps/ieee754/dbl-64/s_ilogb.c.jj Wed Jul 14 01:52:14 1999 +++ libc/sysdeps/ieee754/dbl-64/s_ilogb.c Mon Jun 4 12:26:17 2001 @@ -16,10 +16,12 @@ static char rcsid[] = "$NetBSD: s_ilogb. /* ilogb(double x) * return the binary exponent of non-zero x - * ilogb(0) = 0x80000001 - * ilogb(inf/NaN) = 0x7fffffff (no signal is raised) + * ilogb(0) = FP_ILOGB0 + * ilogb(NaN) = FP_ILOGBNAN (no signal is raised) + * ilogb(+-Inf) = INT_MAX (no signal is raised) */ +#include <limits.h> #include "math.h" #include "math_private.h" @@ -47,7 +49,13 @@ static char rcsid[] = "$NetBSD: s_ilogb. return ix; } else if (hx<0x7ff00000) return (hx>>20)-1023; - else return FP_ILOGBNAN; + else if (FP_ILOGBNAN != INT_MAX) { + /* ISO C99 requires ilogb(+-Inf) == INT_MAX. */ + GET_LOW_WORD(lx,x); + if(((hx^0x7ff00000)|lx) == 0) + return INT_MAX; + } + return FP_ILOGBNAN; } weak_alias (__ilogb, ilogb) #ifdef NO_LONG_DOUBLE --- libc/sysdeps/ieee754/flt-32/s_ilogbf.c.jj Wed Jul 14 02:01:28 1999 +++ libc/sysdeps/ieee754/flt-32/s_ilogbf.c Mon Jun 4 12:32:43 2001 @@ -17,6 +17,7 @@ static char rcsid[] = "$NetBSD: s_ilogbf.c,v 1.4 1995/05/10 20:47:31 jtc Exp $"; #endif +#include <limits.h> #include "math.h" #include "math_private.h" @@ -39,6 +40,11 @@ static char rcsid[] = "$NetBSD: s_ilogbf return ix; } else if (hx<0x7f800000) return (hx>>23)-127; - else return FP_ILOGBNAN; + else if (FP_ILOGBNAN != INT_MAX) { + /* ISO C99 requires ilogbf(+-Inf) == INT_MAX. */ + if (hx==0x7f800000) + return INT_MAX; + } + return FP_ILOGBNAN; } weak_alias (__ilogbf, ilogbf) --- libc/sysdeps/ieee754/ldbl-128/s_ilogbl.c.jj Wed Jul 14 02:08:52 1999 +++ libc/sysdeps/ieee754/ldbl-128/s_ilogbl.c Mon Jun 4 12:38:18 2001 @@ -19,8 +19,9 @@ static char rcsid[] = "$NetBSD: $"; /* ilogbl(long double x) * return the binary exponent of non-zero x - * ilogbl(0) = 0x80000001 - * ilogbl(inf/NaN) = 0x7fffffff (no signal is raised) + * ilogbl(0) = FP_ILOGB0 + * ilogbl(NaN) = FP_ILOGBNAN (no signal is raised) + * ilogbl(+-Inf) = INT_MAX (no signal is raised) */ #include "math.h" @@ -50,6 +51,11 @@ static char rcsid[] = "$NetBSD: $"; return ix; } else if (hx<0x7fff000000000000LL) return (hx>>48)-0x3fff; - else return FP_ILOGBNAN; + else if (FP_ILOGBNAN != INT_MAX) { + /* ISO C99 requires ilogbl(+-Inf) == INT_MAX. */ + if (((hx^0x7fff000000000000LL)|lx) == 0) + return INT_MAX; + } + return FP_ILOGBNAN; } weak_alias (__ilogbl, ilogbl) --- libc/sysdeps/ieee754/ldbl-96/s_ilogbl.c.jj Wed Jul 14 02:13:51 1999 +++ libc/sysdeps/ieee754/ldbl-96/s_ilogbl.c Mon Jun 4 12:35:43 2001 @@ -20,10 +20,12 @@ static char rcsid[] = "$NetBSD: $"; /* ilogbl(long double x) * return the binary exponent of non-zero x - * ilogbl(0) = 0x80000001 - * ilogbl(inf/NaN) = 0x7fffffff (no signal is raised) + * ilogbl(0) = FP_ILOGB0 + * ilogbl(NaN) = FP_ILOGBNAN (no signal is raised) + * ilogbl(+-Inf) = INT_MAX (no signal is raised) */ +#include <limits.h> #include "math.h" #include "math_private.h" @@ -51,6 +53,9 @@ static char rcsid[] = "$NetBSD: $"; return ix; } else if (es<0x7fff) return es-0x3fff; - else return FP_ILOGBNAN; + else if (FP_ILOGBNAN != INT_MAX && (hx|lx) == 0) + /* ISO C99 requires ilogbl(+-Inf) == INT_MAX. */ + return INT_MAX; + return FP_ILOGBNAN; } weak_alias (__ilogbl, ilogbl) Jakub
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |