如何使计算与小数位的数字阶乘的功能?(How to make a function that com

2019-08-17 16:43发布

我怎样才能让计算阶乘(或功能伽玛功能的十进制数在JavaScript)? 例如,我怎么能计算出2.33!

Answer 1:

我可能会发现现有的解决方案......这是Lanczos法的实施,我发现它在瑞典维基百科( http://sv.wikipedia.org/wiki/Gammafunktionen )。 它是用Python编写的,并说是正确的多达15位小数。 我移植它JS,交叉查了一些随机值对( http://www.efunda.com/math/gamma/findgamma.cfm )。

http://jsfiddle.net/Fzy9C/

var g = 7;
var C = [0.99999999999980993, 676.5203681218851, -1259.1392167224028,771.32342877765313, -176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7];

function gamma(z) {

    if (z < 0.5) return Math.PI / (Math.sin(Math.PI * z) * gamma(1 - z));
    else {
        z -= 1;

        var x = C[0];
        for (var i = 1; i < g + 2; i++)
        x += C[i] / (z + i);

        var t = z + g + 0.5;
        return Math.sqrt(2 * Math.PI) * Math.pow(t, (z + 0.5)) * Math.exp(-t) * x;
    }
}

(和ofcourse它不支持虚数,因为JS没有)



Answer 2:

这不是一个简单的问题。 没有对于一个简单的闭合形式的式伽玛函数 。 这就是说,有一些应该满足您的需求的一些数值逼近。

以下的答案必须将使用一种被称为兰克泽斯逼近 。 该公式如下:

其中g是控制近似的精确程度任意选择的常数。 对于较大的g时,近似将更加准确。 A G(z)是这样定义的:

最难的是发现G(z)的,由于P N也与复杂的公式依赖于克定义 。

我不能把太多的功劳下面的代码,因为我只是维基百科页面上写的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);
}

您可以在行动的jsfiddle看到这个 。



Answer 3:

作为替代这里其他的答案,下面是伽玛功能,通过GergőNemes于2007年提出了一个更简单的近似。 (参见维基百科页面斯特灵公式 )。

这可直接在JavaScript中一行来实现:

function gamma(z) {
  return Math.sqrt(2 * Math.PI / z) * Math.pow((1 / Math.E) * (z + 1 / (12 * z - 1 / (10 * z))), z);
}

您可以在行动的jsfiddle看到这个。

这是准确的8个位数针对z> 8,但它仍然是准确的数字更小的Z A屈指可数 。 这是不是很兰克泽斯逼近准确,但它更简单,也稍快 。

需要注意的是伽马函数和阶乘功能略有不同。 阶乘函数可以在伽马函数从而来定义:

function factorial(n) {
  return gamma(n + 1);
}


Answer 4:

只是为了完成@apelsinapa答案纠正整数计算(输入查询的整数倍时,我们没有得到整数解)。

@ apelsinapa的很好的解决方案:

var g = 7;
var C = [0.99999999999980993, 676.5203681218851, -1259.1392167224028,771.32342877765313, -176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7];

function gamma(z) {
    if (z < 0.5) return Math.PI / (Math.sin(Math.PI * z) * gamma(1 - z));
    else {
        z -= 1;

        var x = C[0];
        for (var i = 1; i < g + 2; i++)
        x += C[i] / (z + i);

        var t = z + g + 0.5;
        return Math.sqrt(2 * Math.PI) * Math.pow(t, (z + 0.5)) * Math.exp(-t) * x;
    }
}

并得到整数正确答案:

 function factorialOfNumber(number) {
    if (number % 1 != 0 || number<0){
        return gamma(number + 1);
    }
    else {
        if(number == 0) {
           return 1;
        }
        for(var i = number; --i; ) {
           number *= i;
        }
        return number;
    }
}     


Answer 5:

这里有一个版本,我几年前写的......有点凌乱,但经测试:)

var
    M_GAMMA = [76.18009172947146, -86.50532032941677, 24.01409824083091, -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5],
    M_GAMMAS = 6;

function gammaFn(x) // Modified to JavaScript from "Numerical Recipies in C" by P. Mainwaring
{
    var i = 0, n = ++x, tmp = x + 5.5, ser = 1.000000000190015;
    for (tmp -= (x + 0.5) * Math.log(tmp); i < M_GAMMAS; ++i) ser += M_GAMMA [i] / ++n;
    return Math.log(2.5066282746310005 * ser / x) - tmp;
}

function fact(x) { return x > 1 ? Math.exp(gammaFn(x)) : 1 }

function combin(n, k) { return (Math.exp(gammaFn(n) - gammaFn(n - k) - gammaFn(k)) + 0.5) | 0 } // Ms Excel COMBIN() n! / k!(n - k)!

n = 49; k = 6; alert(fact(n) + ' ' + fact(k) + ' ' + combin(n, k)); // Lottery odds! (13,983,816)

伽马和GAMMALN函数,则:

function gammaLn(x) { return gammaFn(--x) }

function gamma(x) { return Math.exp(gammaLn(x)) }

:-)



Answer 6:

如果你只是想找计算实数的阶乘的函数,那么你只需要从兰克泽斯逼近这段代码:

function = factorial(z) {

  var g = 7;
  var C = [0.99999999999980993, 676.5203681218851, -1259.1392167224028, 771.32342877765313, -176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7];
  var x = C[0];

  for (var i = 1; i < g + 2; i++)
  x += C[i] / (z + i);

  var t = z + g + 0.5;
  return Math.sqrt(2 * Math.PI) * Math.pow(t, (z + 0.5)) * Math.exp(-t) * x;
}

伟大工程,除了小数负数。



文章来源: How to make a function that computes the factorial for numbers with decimals?