Skip to content

Commit d1ec41c

Browse files
committed
math: cleanup gamma.v: remove if true { and gotos; move constants closer to the places that do use them
1 parent 4c8c892 commit d1ec41c

1 file changed

Lines changed: 19 additions & 29 deletions

File tree

‎vlib/math/gamma.v‎

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,20 @@ fn stirling(x f64) (f64, f64) {
1111
if x > 200 {
1212
return inf(1), 1.0
1313
}
14-
sqrt_two_pi := 2.506628274631000502417
15-
max_stirling := 143.01608
1614
mut w := 1.0 / x
1715
w = 1.0 + w * ((((gamma_s[0] * w + gamma_s[1]) * w + gamma_s[2]) * w + gamma_s[3]) * w +
1816
gamma_s[4])
1917
mut y1 := exp(x)
2018
mut y2 := 1.0
21-
if x > max_stirling { // avoid Pow() overflow
19+
if x > 143.01608 { // avoid Pow() overflow, the constant is max_stirling
2220
v := pow(x, 0.5 * x - 0.25)
2321
y1_ := y1
2422
y1 = v
2523
y2 = v / y1_
2624
} else {
2725
y1 = pow(x, x - 0.5) / y1
2826
}
29-
return y1, f64(sqrt_two_pi) * w * y2
27+
return y1, f64(2.506628274631000502417) * w * y2 // the constant is sqrt_two_pi
3028
}
3129

3230
// gamma returns the gamma function of x.
@@ -40,7 +38,6 @@ fn stirling(x f64) (f64, f64) {
4038
// gamma(nan) = nan
4139
pub fn gamma(a f64) f64 {
4240
mut x := a
43-
euler := 0.57721566490153286060651209008240243104215933593992 // A001620
4441
if is_neg_int(x) || is_inf(x, -1) || is_nan(x) {
4542
return nan()
4643
}
@@ -92,18 +89,14 @@ pub fn gamma(a f64) f64 {
9289
}
9390
for x < 0 {
9491
if x > -1e-09 {
95-
unsafe {
96-
goto small
97-
}
92+
return gamma_too_small(x, z)
9893
}
9994
z = z / x
10095
x = x + 1
10196
}
10297
for x < 2 {
10398
if x < 1e-09 {
104-
unsafe {
105-
goto small
106-
}
99+
return gamma_too_small(x, z)
107100
}
108101
z = z / x
109102
x = x + 1
@@ -116,13 +109,14 @@ pub fn gamma(a f64) f64 {
116109
gamma_p[4]) * x + gamma_p[5]) * x + gamma_p[6]
117110
q = ((((((x * gamma_q[0] + gamma_q[1]) * x + gamma_q[2]) * x + gamma_q[3]) * x +
118111
gamma_q[4]) * x + gamma_q[5]) * x + gamma_q[6]) * x + gamma_q[7]
119-
if true {
120-
return z * p / q
121-
}
122-
small:
112+
return z * p / q
113+
}
114+
115+
fn gamma_too_small(x f64, z f64) f64 {
123116
if x == 0 {
124117
return inf(1)
125118
}
119+
euler := 0.57721566490153286060651209008240243104215933593992 // A001620
126120
return z / ((1.0 + euler * x) * x)
127121
}
128122

@@ -142,14 +136,6 @@ pub fn log_gamma(x f64) f64 {
142136
// log_gamma_sign returns the natural logarithm and sign (-1 or +1) of Gamma(x)
143137
pub fn log_gamma_sign(a f64) (f64, int) {
144138
mut x := a
145-
ymin := 1.461632144968362245
146-
tiny := exp2(-70)
147-
two52 := exp2(52) // 0x4330000000000000 ~4.5036e+15
148-
two58 := exp2(58) // 0x4390000000000000 ~2.8823e+17
149-
tc := 1.46163214496836224576e+00 // 0x3FF762D86356BE3F
150-
tf := -1.21486290535849611461e-01 // 0xBFBF19B9BCC38A42
151-
// tt := -(tail of tf)
152-
tt := -3.63867699703950536541e-18 // 0xBC50C7CAA48A971F
153139
mut sign := 1
154140
if is_nan(x) {
155141
return x, sign
@@ -165,15 +151,15 @@ pub fn log_gamma_sign(a f64) (f64, int) {
165151
x = -x
166152
neg = true
167153
}
168-
if x < tiny { // if |x| < 2**-70, return -log(|x|)
154+
if x < exp2(-70) { // if |x| < 2**-70, return -log(|x|)
169155
if neg {
170156
sign = -1
171157
}
172158
return -log(x), sign
173159
}
174160
mut nadj := 0.0
175161
if neg {
176-
if x >= two52 {
162+
if x >= exp2(52) { // the constant is 0x4330000000000000 ~4.5036e+15
177163
// x| >= 2**52, must be -integer
178164
return inf(1), sign
179165
}
@@ -190,6 +176,8 @@ pub fn log_gamma_sign(a f64) (f64, int) {
190176
if x == 1 || x == 2 { // purge off 1 and 2
191177
return 0.0, sign
192178
} else if x < 2 { // use lgamma(x) = lgamma(x+1) - log(x)
179+
ymin := 1.461632144968362245
180+
tc := 1.46163214496836224576e+00 // 0x3FF762D86356BE3F
193181
mut y := 0.0
194182
mut i := 0
195183
if x <= 0.9 {
@@ -234,6 +222,9 @@ pub fn log_gamma_sign(a f64) (f64, int) {
234222
w * lgamma_t[13])))
235223
gamma_p3 := lgamma_t[2] + w * (lgamma_t[5] + w * (lgamma_t[8] + w * (lgamma_t[11] +
236224
w * lgamma_t[14])))
225+
tf := -1.21486290535849611461e-01 // 0xBFBF19B9BCC38A42
226+
// tt := -(tail of tf)
227+
tt := -3.63867699703950536541e-18 // 0xBC50C7CAA48A971F
237228
p := z * gamma_p1 - (tt - w * (gamma_p2 + y * gamma_p3))
238229
lgamma += (tf + p)
239230
} else if i == 2 {
@@ -278,7 +269,7 @@ pub fn log_gamma_sign(a f64) (f64, int) {
278269
z *= (y + 2)
279270
lgamma += log(z)
280271
}
281-
} else if x < two58 { // 8 <= x < 2**58
272+
} else if x < exp2(58) { // 8 <= x < 2**58, which is 0x4390000000000000 ~2.8823e+17
282273
t := log(x)
283274
z := 1.0 / x
284275
y := z * z
@@ -297,8 +288,6 @@ pub fn log_gamma_sign(a f64) (f64, int) {
297288
// sin_pi(x) is a helper function for negative x
298289
fn sin_pi(x_ f64) f64 {
299290
mut x := x_
300-
two52 := exp2(52) // 0x4330000000000000 ~4.5036e+15
301-
two53 := exp2(53) // 0x4340000000000000 ~9.0072e+15
302291
if x < 0.25 {
303292
return -sin(pi * x)
304293
}
@@ -309,10 +298,11 @@ fn sin_pi(x_ f64) f64 {
309298
x = mod(x, 2)
310299
n = int(x * 4)
311300
} else {
312-
if x >= two53 { // x must be even
301+
if x >= exp2(53) { // x must be even; the constant is 0x4340000000000000 ~9.0072e+15
313302
x = 0
314303
n = 0
315304
} else {
305+
two52 := exp2(52) // 0x4330000000000000 ~4.5036e+15
316306
if x < two52 {
317307
z = x + two52 // exact
318308
}

0 commit comments

Comments
 (0)