Back to index

glibc  2.9
s_scalblnf.c
Go to the documentation of this file.
00001 /* s_scalbnf.c -- float version of s_scalbn.c.
00002  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
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: s_scalbnf.c,v 1.4 1995/05/10 20:48:10 jtc Exp $";
00018 #endif
00019 
00020 #include "math.h"
00021 #include "math_private.h"
00022 
00023 #ifdef __STDC__
00024 static const float
00025 #else
00026 static float
00027 #endif
00028 two25   =  3.355443200e+07, /* 0x4c000000 */
00029 twom25  =  2.9802322388e-08,       /* 0x33000000 */
00030 huge   = 1.0e+30,
00031 tiny   = 1.0e-30;
00032 
00033 #ifdef __STDC__
00034        float __scalblnf (float x, long int n)
00035 #else
00036        float __scalblnf (x,n)
00037        float x; long int n;
00038 #endif
00039 {
00040        int32_t k,ix;
00041        GET_FLOAT_WORD(ix,x);
00042         k = (ix&0x7f800000)>>23;          /* extract exponent */
00043         if (k==0) {                       /* 0 or subnormal x */
00044             if ((ix&0x7fffffff)==0) return x; /* +-0 */
00045            x *= two25;
00046            GET_FLOAT_WORD(ix,x);
00047            k = ((ix&0x7f800000)>>23) - 25;
00048            }
00049         if (k==0xff) return x+x;          /* NaN or Inf */
00050         k = k+n;
00051         if (n> 50000 || k >  0xfe)
00052          return huge*copysignf(huge,x); /* overflow  */
00053        if (n< -50000)
00054          return tiny*copysignf(tiny,x);   /*underflow*/
00055         if (k > 0)                        /* normal result */
00056            {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;}
00057         if (k <= -25)
00058            return tiny*copysignf(tiny,x); /*underflow*/
00059         k += 25;                          /* subnormal result */
00060        SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23));
00061         return x*twom25;
00062 }
00063 weak_alias (__scalblnf, scalblnf)