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