Back to index

glibc  2.9
s_ilogbl.c
Go to the documentation of this file.
00001 /* s_ilogbl.c -- long double version of s_ilogb.c.
00002  * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
00003  */
00004 
00005 /*
00006  * ====================================================
00007  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
00008  *
00009  * Developed at SunPro, a Sun Microsystems, Inc. business.
00010  * Permission to use, copy, modify, and distribute this
00011  * software is freely granted, provided that this notice
00012  * is preserved.
00013  * ====================================================
00014  */
00015 
00016 #if defined(LIBM_SCCS) && !defined(lint)
00017 static char rcsid[] = "$NetBSD: $";
00018 #endif
00019 
00020 /* ilogbl(long double x)
00021  * return the binary exponent of non-zero x
00022  * ilogbl(0) = FP_ILOGB0
00023  * ilogbl(NaN) = FP_ILOGBNAN (no signal is raised)
00024  * ilogbl(+-Inf) = INT_MAX (no signal is raised)
00025  */
00026 
00027 #include <limits.h>
00028 #include "math.h"
00029 #include "math_private.h"
00030 
00031 #ifdef __STDC__
00032        int __ilogbl(long double x)
00033 #else
00034        int __ilogbl(x)
00035        long double x;
00036 #endif
00037 {
00038        int64_t hx,lx;
00039        int ix;
00040 
00041        GET_LDOUBLE_WORDS64(hx,lx,x);
00042        hx &= 0x7fffffffffffffffLL;
00043        if(hx <= 0x0001000000000000LL) {
00044            if((hx|lx)==0)
00045               return FP_ILOGB0;    /* ilogbl(0) = FP_ILOGB0 */
00046            else                    /* subnormal x */
00047               if(hx==0) {
00048                   for (ix = -16431; lx>0; lx<<=1) ix -=1;
00049               } else {
00050                   for (ix = -16382, hx<<=15; hx>0; hx<<=1) ix -=1;
00051               }
00052            return ix;
00053        }
00054        else if (hx<0x7fff000000000000LL) return (hx>>48)-0x3fff;
00055        else if (FP_ILOGBNAN != INT_MAX) {
00056            /* ISO C99 requires ilogbl(+-Inf) == INT_MAX.  */
00057            if (((hx^0x7fff000000000000LL)|lx) == 0)
00058               return INT_MAX;
00059        }
00060        return FP_ILOGBNAN;
00061 }
00062 weak_alias (__ilogbl, ilogbl)