Genauigkeitsprobem bei lesen aus Datei
-
Hallo erstmal an alle Forenmember (bin ja neu),
Erstmal grundsätzlich, ich bin wirklich ein Anfänger, also wenn ich hier Codeschnipsel Poste, dann seht mir bitte Wildwestprogrmmierung nach und korrigiert mich auf jeden Fall, auch wenn es mit dem Problem an sich nichts zu tun hat.
Nun zum Problem. Ich möchte aus einer .CSV Datei Float-Werte auslesen und in ein Array schreiben. Allerdings scheinen die Werte nicht 100% korrekt übergeben zu werden. Zum Beispiel:Tabellenwerte(eine Zeile):
0,15.55,139.95,137.17,157.5,162.33
(Spalte 2 wird ignoriert)
Ausgabe am Bildschirm:
Zeile 0, Gamma=139.949997, R=137.169998, G=157.500000, B=162.330002
So, und hier mein Schnipsel:
... while ((c=fgetc(CSV)) != EOF) { if (c == '\n') zeilenzahl++; } printf("Tabelle hat %d Zeilen\n",zeilenzahl); gamma = (float *)malloc(zeilenzahl * sizeof(int *)); r = (float *)malloc(zeilenzahl * sizeof(int *)); g = (float *)malloc(zeilenzahl * sizeof(int *)); b = (float *)malloc(zeilenzahl * sizeof(int *)); fseek(CSV,0,SEEK_SET); while ((fscanf(CSV,"%d,%f,%f,%f,%f,%f\n",&no,&dicke,&gamma[i],&r[i],&g[i],&b[i])) != EOF ) i++; for (i=0; i<zeilenzahl; i++) printf("Zeile %d, Gamma=%f, R=%f, G=%f, B=%f\n",i, gamma[i],r[i],g[i],b[i]); ...
Ihr seht, es scheint so was wie eine "Eckung" (Gegenteil von Rundung :p ) zu sein. Oder ist das nur ein Fehler in der Ausgabe?
Vielen Dank schonmal und MFG!
-
r = (float *)malloc(zeilenzahl * sizeof(int *));
Warum reservierst du Speicher fuer einen Zeiger auf int, der dann auf float als float interpretiert werden soll?
PS: 139.949997 ist wohl der Darstellung von Fliesskommazahlen geschuldet.
-
So ganz genau können Fließkommawerte intern nicht gespeichert werden. Störe dich nicht daran, ist halt so. Du kannst doch einfach bei der Ausgabe mit printf auf 2 Stellen runden lassen ("%.2f").
-
Warum reservierst du Speicher fuer einen Zeiger auf int, der dann auf float als float interpretiert werden soll?
Weil ich ein unkonzentrierter Blödmann bin. Danke.
Allerdings löst das das Problem nicht. Komisch das der Compiler nicht meckert.
_matze schrieb:
So ganz genau können Fließkommawerte intern nicht gespeichert werden. Störe dich nicht daran, ist halt so. Du kannst doch einfach bei der Ausgabe mit printf auf 2 Stellen runden lassen ("%.2f").
Ok, das Problem ist aber nicht die Ausgabe. Mit den Werten soll weiter gerechnet werden und dann stört es.
-
Ein erster Schritt wäre ja schon mal, statt float den genaueren Typ double zu nehmen...
Und in den meisten Fällen macht es praktisch nix aus, ob man nun 1.95 oder 1.949999999999 zum Rechnen nimmt.
-
Ein erster Schritt wäre ja schon mal, statt float den genaueren Typ double zu nehmen...
Das funktioniert. Danke. Aber eigentlich wundert mich das Verhalten, weil float ja für 2 Stellen dicke reichen sollte.
Leider stenkert mein Compiler jetzt rum:
warning: ISO C90 does not support the ‘%lf’ gnu_printf format
Und in den meisten Fällen macht es praktisch nix aus, ob man nun 1.95 oder 1.949999999999 zum Rechnen nimmt.
Da hast du natürlich recht. Aber ich weiß eben nicht genau ob das bei mir tatsächlich der Fall ist.
-
jan_lde schrieb:
gamma = (float *)malloc(zeilenzahl * sizeof(int *));
void* wird nicht gecastet!
gamma = malloc(zeilenzahl * sizeof(int *)); /* Alternativ */ gamma = malloc(zeilenzahl * sizeof(*gamma));
-
Janjan schrieb:
jan_lde schrieb:
gamma = (float *)malloc(zeilenzahl * sizeof(int *));
void* wird nicht gecastet!
gamma = malloc(zeilenzahl * sizeof(int *)); /* Alternativ */ gamma = malloc(zeilenzahl * sizeof(*gamma));
Danke. Diese Syntax hab ich aus dem "C von A bis Z" Buch. Komisch das das falsch ist.
-
jan_lde schrieb:
Janjan schrieb:
jan_lde schrieb:
gamma = (float *)malloc(zeilenzahl * sizeof(int *));
void* wird nicht gecastet!
gamma = malloc(zeilenzahl * sizeof(int *)); /* Alternativ */ gamma = malloc(zeilenzahl * sizeof(*gamma));
Danke. Diese Syntax hab ich aus dem "C von A bis Z" Buch. Komisch das das falsch ist.
Es ist veraltet. In Pre-C89-Zeiten gab malloc einen char-Pointer zurück, statt einen void-Pointer. Den musste man dann eben casten. Aber void* wird implizit in jeden anderen Zeigertyp gecastet.
-
jan_lde schrieb:
Danke. Diese Syntax hab ich aus dem "C von A bis Z" Buch. Komisch das das falsch ist.
Janjan schrieb:
Es ist veraltet. In Pre-C89-Zeiten gab malloc einen char-Pointer zurück, statt einen void-Pointer. Den musste man dann eben casten.
Das Buch ist nicht veraltet, sondern völliger Bullshit.
Einerseits schreibt er, man muß nicht casten, dann tut er's doch, seine Programme wimmeln vor mallocs ohne free, reallocs ohne temporäre Pointer usw.
Lies mal nach:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-263643-and-start-is-10-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-wolf.html
http://www.c-plusplus.net/forum/viewtopic-var-t-is-254882.html
http://www.c-plusplus.net/forum/viewtopic-var-t-is-254601-and-postdays-is-0-and-postorder-is-asc-and-start-is-0.html