Source file src/math/atanh.go

```     1  // Copyright 2010 The Go Authors. All rights reserved.
2  // Use of this source code is governed by a BSD-style
4
5  package math
6
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
9  // and came with this notice. The go code is a simplified
10  // version of the original C.
11  //
12  // ====================================================
14  //
15  // Developed at SunPro, a Sun Microsystems, Inc. business.
16  // Permission to use, copy, modify, and distribute this
17  // software is freely granted, provided that this notice
18  // is preserved.
19  // ====================================================
20  //
21  //
22  // __ieee754_atanh(x)
23  // Method :
24  //	1. Reduce x to positive by atanh(-x) = -atanh(x)
25  //	2. For x>=0.5
26  //	            1              2x                          x
27  //	atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
28  //	            2             1 - x                      1 - x
29  //
30  //	For x<0.5
31  //	atanh(x) = 0.5*log1p(2x+2x*x/(1-x))
32  //
33  // Special cases:
34  //	atanh(x) is NaN if |x| > 1 with signal;
35  //	atanh(NaN) is that NaN with no signal;
36  //	atanh(+-1) is +-INF with signal.
37  //
38
39  // Atanh returns the inverse hyperbolic tangent of x.
40  //
41  // Special cases are:
42  //
43  //	Atanh(1) = +Inf
44  //	Atanh(±0) = ±0
45  //	Atanh(-1) = -Inf
46  //	Atanh(x) = NaN if x < -1 or x > 1
47  //	Atanh(NaN) = NaN
48  func Atanh(x float64) float64 {
49  	if haveArchAtanh {
50  		return archAtanh(x)
51  	}
52  	return atanh(x)
53  }
54
55  func atanh(x float64) float64 {
56  	const NearZero = 1.0 / (1 << 28) // 2**-28
57  	// special cases
58  	switch {
59  	case x < -1 || x > 1 || IsNaN(x):
60  		return NaN()
61  	case x == 1:
62  		return Inf(1)
63  	case x == -1:
64  		return Inf(-1)
65  	}
66  	sign := false
67  	if x < 0 {
68  		x = -x
69  		sign = true
70  	}
71  	var temp float64
72  	switch {
73  	case x < NearZero:
74  		temp = x
75  	case x < 0.5:
76  		temp = x + x
77  		temp = 0.5 * Log1p(temp+temp*x/(1-x))
78  	default:
79  		temp = 0.5 * Log1p((x+x)/(1-x))
80  	}
81  	if sign {
82  		temp = -temp
83  	}
84  	return temp
85  }
86
```

View as plain text