-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathasinh32.go
More file actions
109 lines (106 loc) · 2.42 KB
/
Copy pathasinh32.go
File metadata and controls
109 lines (106 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package floats
// Asinh returns the inverse hyperbolic sine of a.
//
// Special cases are:
//
// ±0.Asinh() = ±0
// ±Inf.Asinh() = ±Inf
// NaN.Asinh() = NaN
func (a Float32) Asinh() Float32 {
// https://github.com/chewxy/math32/blob/912ef0b2e4151df0148d7645c92a7b5e22f887f5/asinh.go#L36-L66
const (
Ln2 = 6.93147180559945286227e-01 // 0x3FE62E42FEFA39EF
NearZero = 1.0 / (1 << 28) // 2**-28
Large = 1 << 28 // 2**28
)
// special cases
if a.IsNaN() || a.IsInf(0) {
return a
}
sign := false
if a < 0 {
a = -a
sign = true
}
var temp Float32
switch {
case a > Large:
temp = a.Log() + Ln2 // |a| > 2**28
case a > 2:
temp = (2*a + 1./((a*a+1).Sqrt()+a)).Log() // 2**28 > |a| > 2.0
case a < NearZero:
temp = a // |a| < 2**-28
default:
temp = (a + a*a/(1+(1+a*a).Sqrt())).Log1p() // 2.0 > |a| > 2**-28
}
if sign {
temp = -temp
}
return temp
}
// Acosh returns the inverse hyperbolic cosine of a.
//
// Special cases are:
//
// +Inf.Acosh() = +Inf
// x.Acosh() = NaN if x < 1
// NaN.Acosh() = NaN
func (a Float32) Acosh() Float32 {
// https://github.com/chewxy/math32/blob/912ef0b2e4151df0148d7645c92a7b5e22f887f5/acosh.go#L40-L53
const Ln2 = 6.93147180559945286227e-01 // 0x3FE62E42FEFA39EF
const Large = 1 << 28 // 2**28
// first case is special case
switch {
case a < 1 || a.IsNaN():
return NewFloat32NaN()
case a == 1:
return 0
case a >= Large:
return a.Log() + Ln2 // a > 2**28
case a > 2:
return (2*a - 1./(a+(a*a-1).Sqrt())).Log() // 2**28 > a > 2
}
t := a - 1
return (t + (2*t + t*t).Sqrt()).Log1p() // 2 >= a > 1
}
// Atanh returns the inverse hyperbolic tangent of a.
//
// Special cases are:
//
// 1.Atanh() = +Inf
// ±0.Atanh() = ±0
// -1.Atanh() = -Inf
// x.Atanh() = NaN if x < -1 or x > 1
// NaN.Atanh() = NaN
func (a Float32) Atanh() Float32 {
// https://github.com/chewxy/math32/blob/912ef0b2e4151df0148d7645c92a7b5e22f887f5/atanh.go#L45-L73
const NearZero = 1.0 / (1 << 28) // 2**-28
// special cases
switch {
case a < -1 || a > 1 || a.IsNaN():
return NewFloat32NaN()
case a == 1:
return NewFloat32Inf(1)
case a == -1:
return NewFloat32Inf(-1)
}
sign := false
if a < 0 {
a = -a
sign = true
}
var temp Float32
switch {
case a < NearZero:
temp = a
case a < 0.5:
temp = a + a
temp = 0.5 * (temp + temp*a/(1-a)).Log1p()
default:
temp = 0.5 * ((a + a) / (1 - a)).Log1p()
}
if sign {
temp = -temp
}
return temp
}