Fixing ilogb()
Stefan Farfeleder
stefanf at FreeBSD.org
Sat May 8 12:48:04 PDT 2004
Hi,
I found two problems with our current ilogb() implemenation(s).
- Both the man page and FP_ILOGB0 claim that ilogb(0) returns INT_MIN
while the implementation in s_ilogb.c returns -INT_MAX. We really
have to decide on one value (both are conforming to C99, I've attached
the text). The attached patch assumes that -INT_MAX is kept.
On a related note, is there a reason why <math.h> doesn't use
<machine/_limit.h>'s __INT_M{AX,IN} for the FP_ILOGB* macros?
- On i386 the assembler file s_ilogb.S is used instead. It uses the
instruction fxtract which returns INT_MIN for 0, infinity and NaN.
Except for infinity this conforms too, but doesn't play well with our
MI definitions for FP_ILOGB*. In the attached patch I've aligned
s_ilogb.S's behaviour with s_ilogb.c, the alternative would be just
fixing infinity and making FP_ILOGB* MD.
Opinions?
Cheers,
Stefan
-------------- next part --------------
7.12 Mathematics <math.h>
8 The macros
FP_ILOGB0
FP_ILOGBNAN
expand to integer constant expressions whose values are returned by ilogb(x) if x is
zero or NaN, respectively. The value of FP_ILOGB0 shall be either INT_MIN or
-INT_MAX. The value of FP_ILOGBNAN shall be either INT_MAX or INT_MIN.
7.12.6.5 The ilogb functions
Synopsis
1 #include <math.h>
int ilogb(double x);
int ilogbf(float x);
int ilogbl(long double x);
Description
2 The ilogb functions extract the exponent of x as a signed int value. If x is zero they
compute the value FP_ILOGB0; if x is infinite they compute the value INT_MAX; if x is
a NaN they compute the value FP_ILOGBNAN; otherwise, they are equivalent to calling
the corresponding logb function and casting the returned value to type int. A range
error may occur if x is 0.
-------------- next part --------------
Index: src/lib/msun/i387/s_ilogb.S
===================================================================
RCS file: /usr/home/ncvs/src/lib/msun/i387/s_ilogb.S,v
retrieving revision 1.8
diff -u -r1.8 s_ilogb.S
--- src/lib/msun/i387/s_ilogb.S 6 Jun 2000 12:12:36 -0000 1.8
+++ src/lib/msun/i387/s_ilogb.S 8 May 2004 18:57:27 -0000
@@ -43,11 +43,27 @@
subl $4,%esp
fldl 8(%ebp)
+ fxam
+ fnstsw %ax
+ sahf
+ jc .L2
+ jnp .L3
+
fxtract
fstp %st
fistpl -4(%ebp)
movl -4(%ebp),%eax
-
+.L1:
leave
ret
+
+.L2:
+ /* Depending on ilogb(NAN) == ilogb(INFINITY) */
+ movl $0x7fffffff,%eax /* FP_ILOGBNAN, INT_MAX */
+ fstp %st
+ jmp .L1
+.L3:
+ movl $0x80000001,%eax /* FP_ILOGB0 */
+ fstp %st
+ jmp .L1
Index: src/lib/msun/man/ieee.3
===================================================================
RCS file: /usr/home/ncvs/src/lib/msun/man/ieee.3,v
retrieving revision 1.13
diff -u -r1.13 ieee.3
--- src/lib/msun/man/ieee.3 7 May 2004 18:56:31 -0000 1.13
+++ src/lib/msun/man/ieee.3 8 May 2004 18:48:29 -0000
@@ -116,11 +116,14 @@
in integer format.
.Fn ilogb \*(Pm\*(If
returns
-.Dv INT_MAX
+.Dv INT_MAX ,
+.Fn ilogb \*(Pm\*(Na
+returns
+.Dv FP_ILOGBNAN
and
.Fn ilogb 0
returns
-.Dv INT_MIN .
+.Dv FP_ILOGB0 .
.Pp
.Fn nextafter
and
Index: src/lib/msun/src/math.h
===================================================================
RCS file: /usr/home/ncvs/src/lib/msun/src/math.h,v
retrieving revision 1.32
diff -u -r1.32 math.h
--- src/lib/msun/src/math.h 7 May 2004 18:56:31 -0000 1.32
+++ src/lib/msun/src/math.h 8 May 2004 18:45:25 -0000
@@ -35,7 +35,7 @@
#define HUGE_VAL (__infinity.__ud)
#if __ISO_C_VISIBLE >= 1999
-#define FP_ILOGB0 (-0x7fffffff - 1) /* INT_MIN */
+#define FP_ILOGB0 (-0x7fffffff) /* -INT_MAX */
#define FP_ILOGBNAN 0x7fffffff /* INT_MAX */
#define HUGE_VALF (float)HUGE_VAL
#define HUGE_VALL (long double)HUGE_VAL
More information about the freebsd-standards
mailing list