这不是一个小问题。 gamma function 没有简单的封闭式公式。也就是说,有一些数值近似值应该适合您的需求。
以下答案将使用一种称为Lanczos approximation 的技术。公式如下:
其中 g 是一个任意选择的常数,用于控制近似值的准确性。对于较大的 g,近似值会更准确。 Ag(z) 定义如下:
最难的部分是找到 Ag(z),因为 pn is also defined with a complicated formula dependent on g。
我不能对下面的代码有太多的功劳,因为我只是在维基百科页面上编写 Python 程序的一个端口。
function gamma(n) { // accurate to about 15 decimal places
//some magic constants
var g = 7, // g represents the precision desired, p is the values of p[i] to plug into Lanczos' formula
p = [0.99999999999980993, 676.5203681218851, -1259.1392167224028, 771.32342877765313, -176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7];
if(n < 0.5) {
return Math.PI / Math.sin(n * Math.PI) / gamma(1 - n);
}
else {
n--;
var x = p[0];
for(var i = 1; i < g + 2; i++) {
x += p[i] / (n + i);
}
var t = n + g + 0.5;
return Math.sqrt(2 * Math.PI) * Math.pow(t, (n + 0.5)) * Math.exp(-t) * x;
}
}
当然,根据伽马函数的定义:
function factorial(n) {
return gamma(n + 1);
}
你可以see this in action on jsFiddle。