OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package math | 5 package math |
6 | 6 |
7 // Ldexp is the inverse of Frexp. | 7 // Ldexp is the inverse of Frexp. |
8 // It returns frac × 2**exp. | 8 // It returns frac × 2**exp. |
| 9 // |
| 10 // Special cases are: |
| 11 // Ldexp(±0, exp) = ±0 |
| 12 // Ldexp(±Inf, exp) = ±Inf |
| 13 // Ldexp(NaN, exp) = NaN |
9 func Ldexp(frac float64, exp int) float64 { | 14 func Ldexp(frac float64, exp int) float64 { |
10 // TODO(rsc): Remove manual inlining of IsNaN, IsInf | 15 // TODO(rsc): Remove manual inlining of IsNaN, IsInf |
11 // when compiler does it for us | 16 // when compiler does it for us |
12 // special cases | 17 // special cases |
13 switch { | 18 switch { |
14 case frac == 0: | 19 case frac == 0: |
15 return frac // correctly return -0 | 20 return frac // correctly return -0 |
16 » case frac != frac: // IsNaN(frac): | 21 » case frac < -MaxFloat64 || frac > MaxFloat64 || frac != frac: // IsInf(f
rac, 0) || IsNaN(frac): |
17 » » return NaN() | 22 » » return frac |
18 } | 23 } |
| 24 frac, e := normalize(frac) |
| 25 exp += e |
19 x := Float64bits(frac) | 26 x := Float64bits(frac) |
20 » exp += int(x>>shift) & mask | 27 » exp += int(x>>shift)&mask - bias |
21 » if exp <= 0 { | 28 » if exp < -1074 { |
22 » » return 0 // underflow | 29 » » return Copysign(0, frac) // underflow |
23 } | 30 } |
24 » if exp >= mask { // overflow | 31 » if exp > 1023 { // overflow |
25 if frac < 0 { | 32 if frac < 0 { |
26 return Inf(-1) | 33 return Inf(-1) |
27 } | 34 } |
28 return Inf(1) | 35 return Inf(1) |
29 } | 36 } |
| 37 var m float64 = 1 |
| 38 if exp < -1022 { // denormal |
| 39 exp += 52 |
| 40 m = 1.0 / (1 << 52) // 2**-52 |
| 41 } |
30 x &^= mask << shift | 42 x &^= mask << shift |
31 » x |= uint64(exp) << shift | 43 » x |= uint64(exp+bias) << shift |
32 » return Float64frombits(x) | 44 » return m * Float64frombits(x) |
33 } | 45 } |
OLD | NEW |