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