Bug 43345 - ilogb(INFINITY) returns incorrect value
Summary: ilogb(INFINITY) returns incorrect value
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: libc   
(Show other bugs)
Version: 7.1
Hardware: i386
OS: Linux
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact:
Depends On:
TreeView+ depends on / blocked
Reported: 2001-06-03 14:44 UTC by Trevin Beattie
Modified: 2008-05-01 15:38 UTC (History)
0 users

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2001-06-05 07:56:31 UTC
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)

External Trackers
Tracker ID Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2001:121 normal SHIPPED_LIVE GNU C Library bugfix update 2001-10-04 04:00:00 UTC

Description Trevin Beattie 2001-06-03 14:44:16 UTC
From Bugzilla Helper:
User-Agent: Mozilla/4.77 [en] (X11; U; Linux 2.4.2-2 i586)

Description of problem:
The ilogb function in glibc apparently returns FP_ILOGBNAN for both
INFINITY and NAN.  On the i386 port, this value is equal to INT_MIN, but
ilogb(INFINITY) is supposed to return INT_MAX.  (On other architectures,
FP_ILOGBNAN is equal to INT_MAX, so it doesn't matter.)  This affects both
the generic C and i386-specific assembly language sources.

How reproducible:

Steps to Reproduce:
Compile and run the following code (don't forget -lm):

#include <limits.h>
#define __USE_ISOC99 1
#include <math.h>
#include <stdio.h>

main ()
  if (ilogb (INFINITY) == INT_MAX) {
      printf ("ilogb(INFINITY) is correct.\n");
      return 0;
    } else {
      printf ("ilogb(INFINITY) returned %d; should be %d.\n",
	      ilogb (INFINITY), INT_MAX);
      return 1;

Actual Results:  ilogb(INFINITY) returned -2147483648; should be

Expected Results:  ilogb(INFINITY) is correct.

Additional info:

This is a requirement of ISO C99, as found in WG14/N869 (; it may
be a new addition since the C90 standard.  The draft standard reads:

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."

Suggested patch:
Something like the following should work:

diff -c glibc-2.2.3/sysdeps/ieee754/dbl-64/s_ilogb.c.orig
*** glibc-2.2.3/sysdeps/ieee754/dbl-64/s_ilogb.c.orig   Tue Jul 13 16:52:14
1999--- glibc-2.2.3/sysdeps/ieee754/dbl-64/s_ilogb.c        Sun Jun  3
07:38:16 2001***************
*** 20,25 ****
--- 20,26 ----
   * ilogb(inf/NaN) = 0x7fffffff (no signal is raised)
+ #include "limits.h"
  #include "math.h"
  #include "math_private.h"
*** 47,53 ****
            return ix;
        else if (hx<0x7ff00000) return (hx>>20)-1023;
!       else return FP_ILOGBNAN;
  weak_alias (__ilogb, ilogb)
--- 48,59 ----
            return ix;
        else if (hx<0x7ff00000) return (hx>>20)-1023;
!       else {
!           GET_LOW_WORD(lx,x);
!           if((hx==0x7ff00000)&&(lx==0))
!               return INT_MAX;
!           else return FP_ILOGBNAN;
!       }
  weak_alias (__ilogb, ilogb)
diff -c glibc-2.2.3/sysdeps/i386/fpu/s_ilogb.S.orig
*** glibc-2.2.3/sysdeps/i386/fpu/s_ilogb.S.orig Tue Jul 13 16:34:41 1999
--- glibc-2.2.3/sysdeps/i386/fpu/s_ilogb.S      Sun Jun  3 07:45:08 2001
*** 9,15 ****
        fldl    4(%esp)
!       fxtract
        pushl   %eax
  fstp    %st
--- 9,24 ----
        fldl    4(%esp)
!       fxam
!       fnstsw
!       andb    $69, %ah
!       cmpb    $5, %ah
!       jne     1f
!       fstp    %st(0)
!       movl    $0x7fffffff, %eax
!       ret
! 1:    fxtract
        pushl   %eax
        fstp    %st

Comment 2 Jakub Jelinek 2001-06-07 13:17:34 UTC
Included in glibc-2.2.3-11.

Note You need to log in before you can comment on or make changes to this bug.