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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.