通过不幸的情况,我发现我的标准库实现 <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!
摘要:历史上的混乱比比皆是;避免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引入。
不建议使用这些函数:而是根据需要使用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)
| 归档时间: |
|
| 查看次数: |
2220 次 |
| 最近记录: |