Back to index

glibc  2.9
s_ilogb.c
Go to the documentation of this file.
00001 /* @(#)s_ilogb.c 5.1 93/09/24 */
00002 /*
00003  * ====================================================
00004  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
00005  *
00006  * Developed at SunPro, a Sun Microsystems, Inc. business.
00007  * Permission to use, copy, modify, and distribute this
00008  * software is freely granted, provided that this notice
00009  * is preserved.
00010  * ====================================================
00011  */
00012 
00013 #if defined(LIBM_SCCS) && !defined(lint)
00014 static char rcsid[] = "$NetBSD: s_ilogb.c,v 1.9 1995/05/10 20:47:28 jtc Exp $";
00015 #endif
00016 
00017 /* ilogb(double x)
00018  * return the binary exponent of non-zero x
00019  * ilogb(0) = FP_ILOGB0
00020  * ilogb(NaN) = FP_ILOGBNAN (no signal is raised)
00021  * ilogb(+-Inf) = INT_MAX (no signal is raised)
00022  */
00023 
00024 #include <limits.h>
00025 #include "math.h"
00026 #include "math_private.h"
00027 
00028 #ifdef __STDC__
00029        int __ilogb(double x)
00030 #else
00031        int __ilogb(x)
00032        double x;
00033 #endif
00034 {
00035        int32_t hx,lx,ix;
00036 
00037        GET_HIGH_WORD(hx,x);
00038        hx &= 0x7fffffff;
00039        if(hx<0x00100000) {
00040            GET_LOW_WORD(lx,x);
00041            if((hx|lx)==0)
00042               return FP_ILOGB0;    /* ilogb(0) = FP_ILOGB0 */
00043            else                    /* subnormal x */
00044               if(hx==0) {
00045                   for (ix = -1043; lx>0; lx<<=1) ix -=1;
00046               } else {
00047                   for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1;
00048               }
00049            return ix;
00050        }
00051        else if (hx<0x7ff00000) return (hx>>20)-1023;
00052        else if (FP_ILOGBNAN != INT_MAX) {
00053            /* ISO C99 requires ilogb(+-Inf) == INT_MAX.  */
00054            GET_LOW_WORD(lx,x);
00055            if(((hx^0x7ff00000)|lx) == 0)
00056               return INT_MAX;
00057        }
00058        return FP_ILOGBNAN;
00059 }
00060 weak_alias (__ilogb, ilogb)
00061 #ifdef NO_LONG_DOUBLE
00062 strong_alias (__ilogb, __ilogbl)
00063 weak_alias (__ilogb, ilogbl)
00064 #endif