1 /* 2 * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * scalbn (double x, int n) 28 * scalbn(x,n) returns x* 2**n computed by exponent 29 * manipulation rather than by actually performing an 30 * exponentiation or a multiplication. 31 */ 32 33 #include "fdlibm.h" 34 35 #ifdef __STDC__ 36 static const double 37 #else 38 static double 39 #endif 40 two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ 41 twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ 42 huge = 1.0e+300, 43 tiny = 1.0e-300; 44 45 #ifdef __STDC__ scalbn(double x,int n)46 double scalbn (double x, int n) 47 #else 48 double scalbn (x,n) 49 double x; int n; 50 #endif 51 { 52 int k,hx,lx; 53 hx = __HI(x); 54 lx = __LO(x); 55 k = (hx&0x7ff00000)>>20; /* extract exponent */ 56 if (k==0) { /* 0 or subnormal x */ 57 if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ 58 x *= two54; 59 hx = __HI(x); 60 k = ((hx&0x7ff00000)>>20) - 54; 61 if (n< -50000) return tiny*x; /*underflow*/ 62 } 63 if (k==0x7ff) return x+x; /* NaN or Inf */ 64 k = k+n; 65 if (k > 0x7fe) return huge*copysign(huge,x); /* overflow */ 66 if (k > 0) /* normal result */ 67 {__HI(x) = (hx&0x800fffff)|(k<<20); return x;} 68 if (k <= -54) { 69 if (n > 50000) /* in case integer overflow in n+k */ 70 return huge*copysign(huge,x); /*overflow*/ 71 else return tiny*copysign(tiny,x); /*underflow*/ 72 } 73 k += 54; /* subnormal result */ 74 __HI(x) = (hx&0x800fffff)|(k<<20); 75 return x*twom54; 76 } 77