LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2010 The Go Authors. All rights reserved. | 1 // Copyright 2010 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 // The original C code, the long comment, and the constants | 7 // The original C code, the long comment, and the constants |
8 // below are from FreeBSD's /usr/src/lib/msun/src/e_atanh.c | 8 // below are from FreeBSD's /usr/src/lib/msun/src/e_atanh.c |
9 // and came with this notice. The go code is a simplified | 9 // and came with this notice. The go code is a simplified |
10 // version of the original C. | 10 // version of the original C. |
(...skipping 28 matching lines...) Expand all Loading... |
39 // Atanh(x) calculates the inverse hyperbolic tangent of x. | 39 // Atanh(x) calculates the inverse hyperbolic tangent of x. |
40 // | 40 // |
41 // Special cases are: | 41 // Special cases are: |
42 // Atanh(1) = +Inf | 42 // Atanh(1) = +Inf |
43 // Atanh(±0) = ±0 | 43 // Atanh(±0) = ±0 |
44 // Atanh(-1) = -Inf | 44 // Atanh(-1) = -Inf |
45 // Atanh(x) = NaN if x < -1 or x > 1 | 45 // Atanh(x) = NaN if x < -1 or x > 1 |
46 // Atanh(NaN) = NaN | 46 // Atanh(NaN) = NaN |
47 func Atanh(x float64) float64 { | 47 func Atanh(x float64) float64 { |
48 const NearZero = 1.0 / (1 << 28) // 2**-28 | 48 const NearZero = 1.0 / (1 << 28) // 2**-28 |
49 // TODO(rsc): Remove manual inlining of IsNaN | |
50 // when compiler does it for us | |
51 // special cases | 49 // special cases |
52 switch { | 50 switch { |
53 » case x < -1 || x > 1 || x != x: // x < -1 || x > 1 || IsNaN(x): | 51 » case x < -1 || x > 1 || IsNaN(x): |
54 return NaN() | 52 return NaN() |
55 case x == 1: | 53 case x == 1: |
56 return Inf(1) | 54 return Inf(1) |
57 case x == -1: | 55 case x == -1: |
58 return Inf(-1) | 56 return Inf(-1) |
59 } | 57 } |
60 sign := false | 58 sign := false |
61 if x < 0 { | 59 if x < 0 { |
62 x = -x | 60 x = -x |
63 sign = true | 61 sign = true |
64 } | 62 } |
65 var temp float64 | 63 var temp float64 |
66 switch { | 64 switch { |
67 case x < NearZero: | 65 case x < NearZero: |
68 temp = x | 66 temp = x |
69 case x < 0.5: | 67 case x < 0.5: |
70 temp = x + x | 68 temp = x + x |
71 temp = 0.5 * Log1p(temp+temp*x/(1-x)) | 69 temp = 0.5 * Log1p(temp+temp*x/(1-x)) |
72 default: | 70 default: |
73 temp = 0.5 * Log1p((x+x)/(1-x)) | 71 temp = 0.5 * Log1p((x+x)/(1-x)) |
74 } | 72 } |
75 if sign { | 73 if sign { |
76 temp = -temp | 74 temp = -temp |
77 } | 75 } |
78 return temp | 76 return temp |
79 } | 77 } |
LEFT | RIGHT |