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

标签 gcc math.h cmath

在不幸的情况下,我发现我的标准库实现 <math.h><cmath> (C++) 显然包含一个函数的定义,其原型(prototype)如下:

double gamma(double x);

虽然我没有看到它在语言标准(我可以访问的草案)中的任何地方列出。

在 Mac OS X 上使用 gcc v4.2.1,该函数的计算结果与 tgamma 相同这实际上是标准中给它的名称。 (reference)

但在 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;
}

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

$ g++ -o gamma_test gamma_test.cpp 
$ ./gamma_test 1.0
gamma( 1 ) = 1

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

最佳答案

总结:历史上的困惑比比皆是;避免 gamma()并使用 tgamma() .

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

没有名为 gamma 的函数在 ISO C 标准库中。

有标准函数称为 lgammatgamma .引用 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);

The lgamma functions compute the natural logarithm of the absolute value of gamma of x. A range error occurs if x is too large. A pole error may occur if x is a negative integer or zero.

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

The tgamma functions compute the gamma function of x. A domain error or pole error may occur if x is a negative integer or zero. A range error occurs if the magnitude of x is too large and may occur if the magnitude of x is too small.

这些函数没有出现在 1990 ISO C 标准中。它们是由 C99 引入的。

引用Linux man page for gamma :

These functions are deprecated: instead, use either the tgamma(3) or the lgamma(3) functions, as appropriate.

For the definition of the Gamma function, see tgamma(3).

  • *BSD版本

    The libm in 4.4BSD and some versions of FreeBSD had a gamma() function that computes the Gamma function, as one would expect.

  • glibc 版本

    Glibc has a gamma() function that is equivalent to lgamma(3) and computes the natural logarithm of the Gamma function.

和一个历史记录:

4.2BSD had a gamma() that computed ln(|Gamma(|x|)|), leaving the sign of Gamma(|x|) in the external integer signgam. In 4.3BSD the name was changed to lgamma(3), and the man page promises

"At some time in the future the name gamma will be rehabilitated and used for the Gamma function"

This did indeed happen in 4.4BSD, where gamma() computes the Gamma function (with no effect on signgam). However, this came too late, and we now have tgamma(3), the "true gamma" function.

gamma不是标准的 C 函数,用 gcc -std=c99 -pedantic 编译或 gcc -std=c11 -pedantic应该至少对任何调用它的尝试产生警告。

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

C 标准似乎没有说明 Gamma 函数是什么。 Linux tgamma() man page确实如此(但如果您尝试使用它,您可能已经知道它是什么):

The Gamma function is defined by

Gamma(x) = integral from 0 to infinity of t^(x-1) e^-t dt

It is defined for every real number except for nonpositive integers.
For nonnegative integral m one has

Gamma(m+1) = m!

and, more generally, for all x:

Gamma(x+1) = x * Gamma(x)

Furthermore, the following is valid for all values of x outside the poles:

Gamma(x) * Gamma(1 - x) = PI / sin(PI * x)

关于gcc - gamma(double x) 的定义是什么?为什么它在两个 gcc 版本上不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18116376/

相关文章:

c++ - 在 Visual Studio 2015 中使用 cmath 时出现大约 200 个错误

c++ - 使用 FLTK 时出现 cmath 错误

c++ - 使用RowMajor和ColMajor数据排列的矩阵行求和的奇怪性能差异

c++ - C++ 和 eigen3 的编译器错误

c - 现在 glibc 中包含数学库了吗?

c++ - 查找 2 个 3D 点之间的距离

c++ - 仅使用库中的某些功能?

C++ 错误 : braces around scalar initializer for type 'bool'

c++ - 静态库中的 PIC 性能

c - 在 C 中使用 sin() 的 math.h 链接器错误