gamma(double x)的定义是什么,为什么在两个gcc版本上不同?

Noa*_*ahR 2 gcc math.h cmath

通过不幸的情况,我发现我的标准库实现 <math.h><cmath>(C ++)显然包含具有原型的函数的定义,例如:

double gamma(double x);
Run Code Online (Sandbox Code Playgroud)

虽然我没有在语言标准的任何地方看到它(我可以使用草稿)。

在Mac OS X上使用gcc v4.2.1,该函数的评估结果与tgamma标准中实际为其指定的名称相同。(参考)

但是在Ubuntu 12.04上的gcc v4.6.3上,该函数的计算结果有所不同。

我根本不理解为什么一个名为函数的函数都可以gamma编译,但是为什么编译器之间的结果不一样?

这是一个简单的测试程序:

#include<iostream>
#include<sstream>
#include<math.h> // or <cmath>

int main(int argc, char **argv)
{
    std::stringstream conversionStream(argv[1]);
    double input;
    conversionStream >> input;
    std::cout << "gamma( " << input << " ) = " << gamma(input) << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译并使用1个参数运行:

$ g++ -o gamma_test gamma_test.cpp 
$ ./gamma_test 1.0
gamma( 1 ) = 1
Run Code Online (Sandbox Code Playgroud)

但是Ubuntu gcc v4.6.3的输出为0!

Kei*_*son 5

摘要:历史上的混乱比比皆是;避免gamma()和使用tgamma()

实现这些功能的是数学库,而不是gcc(编译器)。如果您在MacOS和Ubuntu上看到不同的行为,则可能是因为Ubuntu使用glibc而MacOS使用其他东西。

gammaISO C标准库中没有命名的函数。

有称为lgamma和的标准函数tgamma。引用N1570(2011 ISO C标准的最新草案)第17.12.8.3和17.12.8.4节:

#include <math.h>
double lgamma(double x);
float lgammaf(float x);
long double lgammal(long double x);

lgamma函数函数计算的伽马的绝对值的自然对数X。如果x太大,则会发生范围错误。如果x为负整数或零,则可能会发生极点错误。

#include <math.h>
double tgamma(double x);
float tgammaf(float x);
long double tgammal(long double x);

所述tgamma函数计算的伽马函数X。如果x为负整数或零,则可能会发生域错误或极点错误。如果幅度发生值域错误X过大,如果幅度可能会发生X太小。

这些功能未出现在1990 ISO C标准中。它们由C99引入。

Linux手册页中gamma引用以下内容

不建议使用这些函数:而是根据需要使用tgamma(3)或lgamma(3)函数。

有关Gamma函数的定义,请参见tgamma(3)。

  • * BSD版本

    正如人们所期望的那样,4.4BSD和FreeBSD的某些版本中的libm都有一个gamma()函数来计算Gamma函数。

  • glibc版本

    Glibc具有与lgamma(3)等效的gamma()函数,并计算Gamma函数的自然对数。

和历史注释:

4.2BSD的gamma()计算ln(| Gamma(| x |)|),而Gamma(| x |)的符号保留在外部整数符号中。在4.3BSD中,名称更改为lgamma(3),并且手册页承诺

“将来会重新命名gamma并将其用于Gamma功能”

这确实在4.4BSD中发生,其中gamma()计算Gamma函数(对signgam不起作用)。但是,这来不及了,现在我们有了tgamma(3),即“真正的gamma”功能。

由于gamma这不是标准的C函数,因此对它进行任何尝试的编译gcc -std=c99 -pedantic或编译gcc -std=c11 -pedantic至少应产生警告。

您可能应该使用tgamma()(或lgamma()如果需要自然对数),并避免使用gamma()

C标准似乎没有说什么是Gamma函数。在Linux的tgamma()手册页做(但如果你想使用它,你可能已经知道它是什么):

伽玛函数定义为

Gamma(x)=从0到t ^(x-1)e ^ -t dt的无穷大的整数

除非正整数外,它为每个实数定义。
对于非负整数m

伽玛(m + 1)= m!

并且更普遍地,对于所有x:

伽玛(x + 1)= x *伽玛(x)

此外,以下内容对于极点之外的所有x值均有效:

伽玛(x)*伽玛(1-x)= PI / sin(PI * x)