| The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 1 | /* s_scalbnf.c -- float version of s_scalbn.c. | 
|  | 2 | * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. | 
|  | 3 | */ | 
|  | 4 |  | 
|  | 5 | /* | 
|  | 6 | * ==================================================== | 
|  | 7 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | 
|  | 8 | * | 
|  | 9 | * Developed at SunPro, a Sun Microsystems, Inc. business. | 
|  | 10 | * Permission to use, copy, modify, and distribute this | 
|  | 11 | * software is freely granted, provided that this notice | 
|  | 12 | * is preserved. | 
|  | 13 | * ==================================================== | 
|  | 14 | */ | 
|  | 15 |  | 
|  | 16 | #ifndef lint | 
|  | 17 | static char rcsid[] = "$FreeBSD: src/lib/msun/src/s_scalbnf.c,v 1.8 2005/03/07 04:52:43 das Exp $"; | 
|  | 18 | #endif | 
|  | 19 |  | 
|  | 20 | #include <sys/cdefs.h> | 
|  | 21 |  | 
|  | 22 | #include "math.h" | 
|  | 23 | #include "math_private.h" | 
|  | 24 |  | 
|  | 25 | static const float | 
|  | 26 | two25   =  3.355443200e+07,	/* 0x4c000000 */ | 
|  | 27 | twom25  =  2.9802322388e-08,	/* 0x33000000 */ | 
|  | 28 | huge   = 1.0e+30, | 
|  | 29 | tiny   = 1.0e-30; | 
|  | 30 |  | 
|  | 31 | float | 
|  | 32 | scalbnf (float x, int n) | 
|  | 33 | { | 
|  | 34 | int32_t k,ix; | 
|  | 35 | GET_FLOAT_WORD(ix,x); | 
|  | 36 | k = (ix&0x7f800000)>>23;		/* extract exponent */ | 
|  | 37 | if (k==0) {				/* 0 or subnormal x */ | 
|  | 38 | if ((ix&0x7fffffff)==0) return x; /* +-0 */ | 
|  | 39 | x *= two25; | 
|  | 40 | GET_FLOAT_WORD(ix,x); | 
|  | 41 | k = ((ix&0x7f800000)>>23) - 25; | 
|  | 42 | if (n< -50000) return tiny*x; 	/*underflow*/ | 
|  | 43 | } | 
|  | 44 | if (k==0xff) return x+x;		/* NaN or Inf */ | 
|  | 45 | k = k+n; | 
|  | 46 | if (k >  0xfe) return huge*copysignf(huge,x); /* overflow  */ | 
|  | 47 | if (k > 0) 				/* normal result */ | 
|  | 48 | {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;} | 
|  | 49 | if (k <= -25) | 
|  | 50 | if (n > 50000) 	/* in case integer overflow in n+k */ | 
|  | 51 | return huge*copysignf(huge,x);	/*overflow*/ | 
|  | 52 | else return tiny*copysignf(tiny,x);	/*underflow*/ | 
|  | 53 | k += 25;				/* subnormal result */ | 
|  | 54 | SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); | 
|  | 55 | return x*twom25; | 
|  | 56 | } | 
|  | 57 |  | 
|  | 58 | __strong_reference(scalbnf, ldexpf); |