根据这个站点,错误函数erf(x)来自math.h. 但实际上看看math.h,它不存在,而gcc无法编译以下测试程序,而g ++可以:
#include#include int main(int argc, char* argv[]) { double x; double erfX; x = 1.0; erfX = erf(x); printf("erf(%f) = %f", x, erfX); } $ gcc mathHTest.c /tmp/ccWfNox5.o: In function `main': mathHTest.c:(.text+0x28): undefined reference to `erf' collect2: ld returned 1 exit status $ g++ mathHTest.c
g ++没有g ++带来什么?查看/ usr/include,我能找到的唯一的地方erf(x)是在tgmath.h中,我没有包括.所以g ++必须抓住比gcc更多的标题,但是哪些?
编辑:我没有在libm与gcc链接,因此链接错误.但是,我仍然不明白为什么erf()不在math.h中.它来自哪里?
我有一个类似的问题,需要找到确切的定义,erf
所以让我扩展这个.正如Chris Dodd所说,声明了函数,bits/mathcalls.h
其中包含了函数maths.h
.
bits/mathcalls.h
:
... #if defined __USE_MISC || defined __USE_XOPEN || defined __USE_ISOC99 __BEGIN_NAMESPACE_C99 /* Error and gamma functions. */ __MATHCALL (erf,, (_Mdouble_)); __MATHCALL (erfc,, (_Mdouble_)); __MATHCALL (lgamma,, (_Mdouble_)); __END_NAMESPACE_C99 #endif ...
宏魔法扩展__MATHCALL (erf,, (_Mdouble_));
到
extern double erf (double) throw (); extern double __erf (double) throw ();
实际代码在libm.a
或libm.so
(gcc -lm
)中:
$ nm /usr/lib/libm.a ... s_erf.o: 00000400 T __erf 00000000 T __erfc U __ieee754_exp 00000400 W erf 00000000 W erfc ...
源可以从gnu libc网页获得.关于实际实现的粗略想法,这里有几行来源:
sysdeps/ieee754/dbl-64/s_erf.c
:
/* double erf(double x) * double erfc(double x) * x * 2 |\ * erf(x) = --------- | exp(-t*t)dt * sqrt(pi) \| * 0 * * erfc(x) = 1-erf(x) * Note that * erf(-x) = -erf(x) * erfc(-x) = 2 - erfc(x) * * Method: * 1. For |x| in [0, 0.84375] * erf(x) = x + x*R(x^2) * erfc(x) = 1 - erf(x) if x in [-.84375,0.25] * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375] * where R = P/Q where P is an odd poly of degree 8 and * Q is an odd poly of degree 10. * -57.90 * | R - (erf(x)-x)/x | <= 2 * * * Remark. The formula is derived by noting * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) * and that * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 * is close to one. The interval is chosen because the fix * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is * near 0.6174), and by some experiment, 0.84375 is chosen to * guarantee the error is less than one ulp for erf. * * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and ...