• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright JS Foundation and other contributors, http://js.foundation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  *
15  * This file is based on work under the following copyright and permission
16  * notice:
17  *
18  *     Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
19  *
20  *     Developed at SunSoft, a Sun Microsystems, Inc. business.
21  *     Permission to use, copy, modify, and distribute this
22  *     software is freely granted, provided that this notice
23  *     is preserved.
24  *
25  *     @(#)s_scalbn.c 1.3 95/01/18
26  */
27 
28 #include "jerry-libm-internal.h"
29 
30 /* scalbn(x,n) returns x* 2**n  computed by  exponent
31  * manipulation rather than by actually performing an
32  * exponentiation or a multiplication.
33  */
34 
35 #define two54  1.80143985094819840000e+16 /* 0x43500000, 0x00000000 */
36 #define twom54 5.55111512312578270212e-17 /* 0x3C900000, 0x00000000 */
37 #define huge   1.0e+300
38 #define tiny   1.0e-300
39 
40 double
scalbn(double x,int n)41 scalbn (double x, int n)
42 {
43   int k, hx, lx;
44 
45   hx = __HI (x);
46   lx = __LO (x);
47   k = (hx & 0x7ff00000) >> 20; /* extract exponent */
48   if (k == 0) /* 0 or subnormal x */
49   {
50     if ((lx | (hx & 0x7fffffff)) == 0) /* +-0 */
51     {
52       return x;
53     }
54     x *= two54;
55     hx = __HI (x);
56     k = ((hx & 0x7ff00000) >> 20) - 54;
57     if (n < -50000) /*underflow */
58     {
59       return tiny * x;
60     }
61   }
62   if (k == 0x7ff) /* NaN or Inf */
63   {
64     return x + x;
65   }
66   k = k + n;
67   if (k > 0x7fe) /* overflow  */
68   {
69     return huge * copysign (huge, x);
70   }
71   if (k > 0) /* normal result */
72   {
73     double_accessor ret;
74     ret.dbl = x;
75     ret.as_int.hi = (hx & 0x800fffff) | (k << 20);
76     return ret.dbl;
77   }
78   if (k <= -54)
79   {
80     if (n > 50000) /* in case integer overflow in n + k */
81     {
82       return huge * copysign (huge, x); /*overflow */
83     }
84     else
85     {
86       return tiny * copysign (tiny, x); /*underflow */
87     }
88   }
89   k += 54; /* subnormal result */
90   double_accessor ret;
91   ret.dbl = x;
92   ret.as_int.hi = (hx & 0x800fffff) | (k << 20);
93   return ret.dbl * twom54;
94 } /* scalbn */
95 
96 #undef two54
97 #undef twom54
98 #undef huge
99 #undef tiny
100