总结:历史上的混乱比比皆是;避免gamma()
和使用tgamma()
.
实现这些功能的是数学库,而不是 gcc(编译器)。如果您在 MacOS 和 Ubuntu 上看到不同的行为,可能是因为 Ubuntu 使用 glibc 而 MacOS 使用其他东西。
gamma
ISO 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的 gamma 绝对值的自然对数。如果x太大,则会发生范围错误。如果x为负整数或零,则可能会出现极点错误。
#include <math.h>
double tgamma(double x);
float tgammaf(float x);
long double tgammal(long double x);
tgamma函数计算 x 的gamma函数。如果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 有一个gamma () 函数,它等效于lgamma (3) 并计算 Gamma 函数的自然对数。
和一个历史记录:
4.2BSD 有一个gamma () 计算 ln(|Gamma(|x|)|),将 Gamma(|x|) 的符号留在外部整数 signgam 中。在 4.3BSD 中,名称更改为lgamma (3),并且手册页承诺
“在未来的某个时候,伽玛这个名字将被恢复并用于伽玛函数”
这确实发生在 4.4BSD 中,其中gamma () 计算 Gamma 函数(对 signgam 没有影响)。然而,这来得太晚了,我们现在有了tgamma (3),即“真正的 gamma”函数。
由于gamma
不是标准的 C 函数,使用gcc -std=c99 -pedantic
or编译gcc -std=c11 -pedantic
至少应该对任何调用它的尝试产生警告。
您可能应该使用tgamma()
(或者lgamma()
如果您想要自然对数)并避免使用gamma()
.
C 标准似乎没有说明 Gamma 函数是什么。Linux tgamma() 手册页确实如此(但如果您尝试使用它,您可能已经知道它是什么):
Gamma 函数定义为
Gamma(x) = 从 0 到无穷大的积分 t^(x-1) e^-t dt
它是为每个实数定义的,除了非正整数。
对于非负积分 m 有
伽玛(m+1) = m!
并且,更一般地,对于所有 x:
伽玛(x+1) = x * 伽玛(x)
此外,以下对于极点外的所有 x 值均有效:
Gamma(x) * Gamma(1 - x) = PI / sin(PI * x)