Fixing ilogb()

Stefan Farfeleder stefanf at
Sat May 8 12:48:04 PDT 2004


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.


-------------- next part --------------
7.12 Mathematics <math.h>

8 The macros
  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. The ilogb functions
1        #include <math.h>
         int ilogb(double x);
         int ilogbf(float x);
         int ilogbl(long double x);
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
 	fstp	%st
 	fistpl	-4(%ebp)
 	movl	-4(%ebp),%eax
+	/* Depending on ilogb(NAN) == ilogb(INFINITY) */
+	movl	$0x7fffffff,%eax	/* FP_ILOGBNAN, INT_MAX */
+	fstp	%st
+	jmp .L1
+	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
+.Dv INT_MAX ,
+.Fn ilogb \*(Pm\*(Na
 .Fn ilogb 0
-.Dv INT_MIN .
+.Dv FP_ILOGB0 .
 .Fn nextafter
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