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 #include <math_ldbl_opt.h>
00031 
00032 #ifdef __STDC__
00033        int __ilogbl(long double x)
00034 #else
00035        int __ilogbl(x)
00036        long double x;
00037 #endif
00038 {
00039        int64_t hx,lx;
00040        int ix;
00041 
00042        GET_LDOUBLE_WORDS64(hx,lx,x);
00043        hx &= 0x7fffffffffffffffLL;
00044        if(hx <= 0x0010000000000000LL) {
00045            if((hx|(lx&0x7fffffffffffffffLL))==0)
00046               return FP_ILOGB0;    /* ilogbl(0) = FP_ILOGB0 */
00047            else                    /* subnormal x */
00048               if(hx==0) {
00049                   for (ix = -1043; lx>0; lx<<=1) ix -=1;
00050               } else {
00051                   for (ix = -1022, hx<<=11; hx>0; hx<<=1) ix -=1;
00052               }
00053            return ix;
00054        }
00055        else if (hx<0x7ff0000000000000LL) return (hx>>52)-0x3ff;
00056        else if (FP_ILOGBNAN != INT_MAX) {
00057            /* ISO C99 requires ilogbl(+-Inf) == INT_MAX.  */
00058            if (((hx^0x7ff0000000000000LL)|lx) == 0)
00059               return INT_MAX;
00060        }
00061        return FP_ILOGBNAN;
00062 }
00063 long_double_symbol (libm, __ilogbl, ilogbl);