1
1
# Float64 version adapted from Cephes Mathematical Library (MIT license https://en.smath.com/view/CephesMathLibrary/license) by Stephen L. Moshier
2
- function gamma (x :: Float64 )
2
+ function gamma (_x :: Float64 )
3
3
T = Float64
4
+ x = _x
4
5
if x < 0
5
- ( isinteger (x) || x == - Inf ) && throw ( DomainError (x, " NaN result for non-NaN input. " ) )
6
- xp1 = abs (x) + 1.0
7
- return π / ( sinpi (xp1) * _gamma (xp1))
6
+ s = sinpi (_x )
7
+ s == 0 && throw ( DomainError (x, " NaN result for non-NaN input. " ))
8
+ x = 1.0 - x
8
9
end
9
- isfinite (x) || return x
10
10
if x > 11.5
11
11
w = inv (x)
12
12
s = (
@@ -17,34 +17,39 @@ function gamma(x::Float64)
17
17
w = muladd (w, evalpoly (w, s), 1.0 )
18
18
# avoid overflow
19
19
v = x ^ muladd (0.5 , x, - 0.25 )
20
- y = v * (v / exp (x))
21
20
22
- return SQ2PI (T) * y * w
21
+ res = SQ2PI (T) * v * (v / exp (x)) * w
22
+
23
+ if _x < 0
24
+ return π / (res * s)
25
+ else
26
+ return res
27
+ end
23
28
end
24
29
P = (
25
- 1.000000000000000000009e0 , 8.378004301573126728826e-1 , 3.629515436640239168939e-1 , 1.113062816019361559013e-1 ,
26
- 2.385363243461108252554e-2 , 4.092666828394035500949e-3 , 4.542931960608009155600e-4 , 4.212760487471622013093e-5
30
+ 1.000000000000000000009e0 , 8.378004301573126728826e-1 , 3.629515436640239168939e-1 , 1.113062816019361559013e-1 ,
31
+ 2.385363243461108252554e-2 , 4.092666828394035500949e-3 , 4.542931960608009155600e-4 , 4.212760487471622013093e-5
27
32
)
28
33
Q = (
29
- 9.999999999999999999908e-1 , 4.150160950588455434583e-1 , - 2.243510905670329164562e-1 , - 4.633887671244534213831e-2 ,
30
- 2.773706565840072979165e-2 , - 7.955933682494738320586e-4 , - 1.237799246653152231188e-3 , 2.346584059160635244282e-4 ,
31
- - 1.397148517476170440917e-5
34
+ 9.999999999999999999908e-1 , 4.150160950588455434583e-1 , - 2.243510905670329164562e-1 , - 4.633887671244534213831e-2 ,
35
+ 2.773706565840072979165e-2 , - 7.955933682494738320586e-4 , - 1.237799246653152231188e-3 , 2.346584059160635244282e-4 ,
36
+ - 1.397148517476170440917e-5
32
37
)
33
38
34
39
z = 1.0
35
40
while x >= 3.0
36
- x -= 1.0
37
- z *= x
41
+ x -= 1.0
42
+ z *= x
38
43
end
39
44
while x < 2.0
40
- z /= x
41
- x += 1.0
45
+ z /= x
46
+ x += 1.0
42
47
end
43
48
44
49
x -= 2.0
45
50
p = evalpoly (x, P)
46
51
q = evalpoly (x, Q)
47
- return z * p / q
52
+ retrun _x < 0 ? π * q / (s * z * p) : z * p / q
48
53
end
49
54
50
55
function gamma (_x:: Float32 )
@@ -89,7 +94,6 @@ function gamma(_x::Float16)
89
94
return Float16 (_x < 0 ? Float32 (π)* den / (s* z* num) : z * num / den)
90
95
end
91
96
92
- _gamma (x) = gamma (x) # easier than fixing this in other places.
93
97
function gamma (n:: Integer )
94
98
n < 0 && throw (DomainError (n, " `n` must not be negative." ))
95
99
n == 0 && return Inf * one (n)
0 commit comments