Back to index

glibc  2.9
s_frexpl.c
Go to the documentation of this file.
00001 /* s_frexpl.c -- long double version of s_frexp.c.
00002  * Conversion to long double by Ulrich Drepper,
00003  * Cygnus Support, drepper@cygnus.com.
00004  */
00005 
00006 /*
00007  * ====================================================
00008  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
00009  *
00010  * Developed at SunPro, a Sun Microsystems, Inc. business.
00011  * Permission to use, copy, modify, and distribute this
00012  * software is freely granted, provided that this notice
00013  * is preserved.
00014  * ====================================================
00015  */
00016 
00017 #if defined(LIBM_SCCS) && !defined(lint)
00018 static char rcsid[] = "$NetBSD: $";
00019 #endif
00020 
00021 /*
00022  * for non-zero x
00023  *     x = frexpl(arg,&exp);
00024  * return a long double fp quantity x such that 0.5 <= |x| <1.0
00025  * and the corresponding binary exponent "exp". That is
00026  *     arg = x*2^exp.
00027  * If arg is inf, 0.0, or NaN, then frexpl(arg,&exp) returns arg
00028  * with *exp=0.
00029  */
00030 
00031 #include <float.h>
00032 #include "math.h"
00033 #include "math_private.h"
00034 
00035 #ifdef __STDC__
00036 static const long double
00037 #else
00038 static long double
00039 #endif
00040 #if LDBL_MANT_DIG == 64
00041 two65 =  3.68934881474191032320e+19L; /* 0x4040, 0x80000000, 0x00000000 */
00042 #else
00043 # error "Cannot handle this MANT_DIG"
00044 #endif
00045 
00046 
00047 #ifdef __STDC__
00048        long double __frexpl(long double x, int *eptr)
00049 #else
00050        long double __frexpl(x, eptr)
00051        long double x; int *eptr;
00052 #endif
00053 {
00054        u_int32_t se, hx, ix, lx;
00055        GET_LDOUBLE_WORDS(se,hx,lx,x);
00056        ix = 0x7fff&se;
00057        *eptr = 0;
00058        if(ix==0x7fff||((ix|hx|lx)==0)) return x; /* 0,inf,nan */
00059        if (ix==0x0000) {           /* subnormal */
00060            x *= two65;
00061            GET_LDOUBLE_EXP(se,x);
00062            ix = se&0x7fff;
00063            *eptr = -65;
00064        }
00065        *eptr += ix-16382;
00066        se = (se & 0x8000) | 0x3ffe;
00067        SET_LDOUBLE_EXP(x,se);
00068        return x;
00069 }
00070 weak_alias (__frexpl, frexpl)