s_scalbnf.c revision 8870
110216Sphk/* s_scalbnf.c -- float version of s_scalbn.c.
210216Sphk * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
310216Sphk */
410216Sphk
510216Sphk/*
610216Sphk * ====================================================
7139825Simp * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8139825Simp *
910216Sphk * Developed at SunPro, a Sun Microsystems, Inc. business.
1010216Sphk * Permission to use, copy, modify, and distribute this
1110216Sphk * software is freely granted, provided that this notice
1210216Sphk * is preserved.
1310216Sphk * ====================================================
1410216Sphk */
1510216Sphk
1610216Sphk#ifndef lint
1710216Sphkstatic char rcsid[] = "$Id: s_scalbnf.c,v 1.1.1.1 1994/08/19 09:39:58 jkh Exp $";
1810216Sphk#endif
1910216Sphk
2010216Sphk#include "math.h"
2110216Sphk#include "math_private.h"
2210216Sphk
2310216Sphk#ifdef __STDC__
2410216Sphkstatic const float
2510216Sphk#else
2610216Sphkstatic float
2710216Sphk#endif
2810216Sphktwo25   =  3.355443200e+07,	/* 0x4c000000 */
2910216Sphktwom25  =  2.9802322388e-08,	/* 0x33000000 */
3010216Sphkhuge   = 1.0e+30,
3110216Sphktiny   = 1.0e-30;
3259656Siwasaki
3359656Siwasaki#ifdef __STDC__
3459656Siwasaki	float scalbnf (float x, int n)
3510216Sphk#else
3610216Sphk	float scalbn (x,n)
3710216Sphk	float x; int n;
3810216Sphk#endif
3910216Sphk{
4010216Sphk	int32_t k,ix;
4110216Sphk	GET_FLOAT_WORD(ix,x);
4210216Sphk        k = (ix&0x7f800000)>>23;		/* extract exponent */
4310216Sphk        if (k==0) {				/* 0 or subnormal x */
4410216Sphk            if ((ix&0x7fffffff)==0) return x; /* +-0 */
4510216Sphk	    x *= two25;
4610216Sphk	    GET_FLOAT_WORD(ix,x);
4710216Sphk	    k = ((ix&0x7f800000)>>23) - 25;
4810216Sphk            if (n< -50000) return tiny*x; 	/*underflow*/
4959656Siwasaki	    }
5059656Siwasaki        if (k==0xff) return x+x;		/* NaN or Inf */
5159656Siwasaki        k = k+n;
5210216Sphk        if (k >  0xfe) return huge*copysignf(huge,x); /* overflow  */
5310216Sphk        if (k > 0) 				/* normal result */
5459656Siwasaki	    {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;}
5559656Siwasaki        if (k <= -25)
5659656Siwasaki            if (n > 50000) 	/* in case integer overflow in n+k */
5759656Siwasaki		return huge*copysignf(huge,x);	/*overflow*/
5859656Siwasaki	    else return tiny*copysignf(tiny,x);	/*underflow*/
5959656Siwasaki        k += 25;				/* subnormal result */
6010216Sphk	SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23));
6110216Sphk        return x*twom25;
6210216Sphk}
6310216Sphk