float-Rundungsfehler (INF) bei Verwendung der glibc sourcen

Gast #2124232
Lesenswert?

Hallo alle,

hoffe es sind einige mathe-cracks unter euch, bzw. jemand der gut mit 
floating point ist :)

Habe mir einige sourcen u.a. aus der glibc gezogen, beispielsweise:
powf(): http://ftp.gnu.org/gnu/glibc/glibc-2.9.tar.gz -> 
glibc-2.9/sysdeps/ieee754/flt-32/e_powf.c
und expf(): http://lxr.e2g.org/source/bionic/libm/src/e_expf.c

Wenn ich diese sourcen anstelle der Librarys direkt in meinen Code 
einbaue bekomme ich das Problem, das im Grenzbereich nicht korrekt 
gerundet wird, bzw. nicht auf +/-INF, ansonsten wir richtig gerechnet:

powf(100.0,100.0)    = 1.#INF00
my_powf(100.0,100.0) = 
1000000030094932700000000000000000000000000000000000000000000.000000

expf(100.000000)    = 1.#INF00
my_expf(100.000000) = 
1000000030094932700000000000000000000000000000000000000000000.000000

Kann mir jemand nen Tipp geben woran das liegt? Wo ist der Unterschied? 
IDE ist Eclipse + MinGW GCC unter XP, das ganze soll aber später auf ner 
embedded 32-bit CPU laufen.

Vielen Dank.
Alec
Gast #2124862
Lesenswert?

Ausgabe erfolgt via printf("%f"). Habe auch schon gemerkt, das es daran 
liegt und nicht an der Berechnung in der Funktion. Denn binär sind die 
Ergebnisse identisch.
Wenn ich beide Funktionsergebnisse einer float-variablen zuweise und 
diese dann ausgebe, stimmt auch die ausgabe via printf().
Kann mir jemand erläutern warum?

f1=expf(f);      printf("   expf(%f) = %f [%X]\n",f,f1,*((int*)&f1));
f2=my_expf(f);   printf("my_expf(%f) = %f [%X]\n",f,f2,*((int*)&f2));
   expf(12345678.000000) = 1.#INF00 [7F800000]
my_expf(12345678.000000) = 1.#INF00 [7F800000]

printf("   expf(%f) = %f\n",f,expf(f));
printf("my_expf(%f) = %f\n",f,my_expf(f));
   expf(12345678.000000) = 1.#INF00
my_expf(12345678.000000) = 
1000000030094932700000000000000000000000000000000000000000000.000000
#2124869
Lesenswert?

Alec schrieb:

> Wenn ich beide Funktionsergebnisse einer float-variablen zuweise und
> diese dann ausgebe, stimmt auch die ausgabe via printf().
> Kann mir jemand erläutern warum?

Du hast weiter oben erwähnt, dass das ganze auf eine 32 Bit CPU soll.

Hast du dort echte double?

float != double

float hat wesentlich geringere Genauigkeit. Kein Wunder, hat ja auch 
weniger Bits zur Verfügung.

Speicherst du ein double Ergebnis, ehe es von einer Funktion die double 
erwartet weiterverarbeitet wird, zwischendurch in einer float Variablen 
ab, dann verlierst du dabei Bits.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren