Frage

Nach diese Seite die Fehlerfunktion erf (x) kommt von Datei math.h. Aber eigentlich in math.h sucht, ist es nicht da ist, und gcc kann folgendes Testprogramm nicht kompiliert werden, während g ++ kann:

#include <math.h>
#include <stdio.h>

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

Was bedeutet g ++ in diesem gcc nicht ziehen? Suchen Sie in / usr / include, ich der einzige Ort erf finden konnte (x) war in tgmath.h, die ich nicht enthalten. So g ++ müssen unterschiedliche Header als gcc werden greifen, aber welche?

EDIT: Ich war die Verknüpfung nicht in libm mit gcc, daher der Link-Fehler. Aber ich verstehe immer noch nicht, warum erf () ist nicht in der Datei math.h. Wo kommen sie her?

War es hilfreich?

Lösung

'erf' ist eigentlich in Bits / mathcalls.h erklärt, die von der Datei math.h. #include wird Die tatsächliche Erklärung ist stark von Makro Magie verdeckt es das Richtige für beide C und C ++ auszukommen

Andere Tipps

Ich hatte ein ähnliches Problem und notwendig, um die genaue Definition von erf zu finden, so lassen Sie mich auf diese erweitern. Wie gesagt von Chris Dodd ist die Funktion in bits/mathcalls.h erklärt, das von maths.h enthalten ist.

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
...

Makro Magie erweitert __MATHCALL (erf,, (_Mdouble_)); zu

extern double erf (double) throw (); extern double __erf (double) throw ();

Der eigentliche Code ist in libm.a oder 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
...

Die Quelle kann aus dem NYS erhalten werden Website. Für eine grobe Vorstellung von der tatsächlichen Implementierung hier ein paar Zeilen der Quelle:

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     
 ...

Sie müssen die Mathematik-Bibliothek (libm) verknüpfen:

$ gcc mathHTest.c -lm

Alle der normalen Mathematik-Bibliothek Funktionen sind wirklich da, und nicht in der Standard-C-Bibliothek (libc).

Nach meinen Tests g++ enthält libm automatisch, aber gcc nicht.

Ich hatte das gleiche Problem gcc von Cygwin auf einem x86-Prozessor. Die „-Im“ Bibliothek umfasst Parameter (nach der Dateiliste!) Funktionierte perfekt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top