Skip to content

Commit 1962b8d

Browse files
authored
Float64 improvements
1 parent 8505ae6 commit 1962b8d

File tree

1 file changed

+22
-18
lines changed

1 file changed

+22
-18
lines changed

src/gamma.jl

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# 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)
33
T = Float64
4+
x = _x
45
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
89
end
9-
isfinite(x) || return x
1010
if x > 11.5
1111
w = inv(x)
1212
s = (
@@ -17,34 +17,39 @@ function gamma(x::Float64)
1717
w = muladd(w, evalpoly(w, s), 1.0)
1818
# avoid overflow
1919
v = x ^ muladd(0.5, x, -0.25)
20-
y = v * (v / exp(x))
2120

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
2328
end
2429
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
2732
)
2833
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
3237
)
3338

3439
z = 1.0
3540
while x >= 3.0
36-
x -= 1.0
37-
z *= x
41+
x -= 1.0
42+
z *= x
3843
end
3944
while x < 2.0
40-
z /= x
41-
x += 1.0
45+
z /= x
46+
x += 1.0
4247
end
4348

4449
x -= 2.0
4550
p = evalpoly(x, P)
4651
q = evalpoly(x, Q)
47-
return z * p / q
52+
retrun _x < 0 ? π * q / (s * z * p) : z * p / q
4853
end
4954

5055
function gamma(_x::Float32)
@@ -89,7 +94,6 @@ function gamma(_x::Float16)
8994
return Float16(_x < 0 ? Float32(π)*den / (s*z*num) : z * num / den)
9095
end
9196

92-
_gamma(x) = gamma(x) #easier than fixing this in other places.
9397
function gamma(n::Integer)
9498
n < 0 && throw(DomainError(n, "`n` must not be negative."))
9599
n == 0 && return Inf*one(n)

0 commit comments

Comments
 (0)