Fließkomma - Wie hole ich mehr Genauigkeit heraus?
-
Hallo,
folgendes Beispiel gibt -3.01755e-20 aus.
int main() { double w = -0.00161579; double rho = -3.23158e-05; double Igrad = 0.0004; const double gamma = 0.02; w = w - rho * gamma / Igrad; std::cout << w << std::endl; }Das Ergebnis ist - für meinen Anwendungsfall - zu ungenau. Eine Maschine muss gesteuert werden.
Matlab gibt mir -2.168404344971009e-19 heraus. Damit wäre ich zufrieden. Das Irre an der Sache ist, das der C-Compiler von Matlab dasselbe Ergebnis wie Matlab liefert. Aber g++ versagt. Ansonsten ist der Matlab-C-Compiler Müll.Was ist zu tun

Danke im voraus
-
http://ideone.com/EXfFr
geht doch
vlt neuen gcc oder irgendwelche optimierungen, fastmath oder wie das heißt.
-
Bei mir passt es. -2.16840434497101e-19. Hast du irgendeinen komischen Compiler, bei dem double nicht 64-Bit hat? Oder irgendwelche komischen Compilerschalter aktiviert?
-
Echt? Bei dir läuft's? Ich habe Ubuntu 32 Bit mit g++ 4.6. Was hast du? Der Matlab-C-Compiler läuft auf der selben Maschine.
-
-3.01755e-20 ist doch vom Betrag her viel kleiner, also genauer.
-
Wird Zeit für 64 bit...
-
SeppJ schrieb:
Bei mir passt es. -2.16840434497101e-19.
-3.01755e-020
GCC 4.6.2
-Wall
-Wextra
-std=c++0xIst aber ein MinGW 32 Bit.
-
goran schrieb:
Wird Zeit für 64 bit...
Das hat damit nichts zu tun. double sollte auch auf 32 Bit Architekturen 64 Bit gross sein. Btw. Verwendest du Intel oder AMD?
-
Intel
-
-2.16840434497101e-19 ist das Ergebnis welches näher an der Wahrheit liegt.
-
Auch auf 32-Bit Systemen hat ein double in der Regel doppelte Genauigkeit. -3.01755e-20 kommt raus, wenn du mit vierfacher Genauigkeit (meistens long double) rechnest.
-
goran schrieb:
-2.16840434497101e-19 ist das Ergebnis welches näher an der Wahrheit liegt.
Und die hast du wie festgestellt? Wie dem auch sei: Wenn das eine Rolle spielt, dann solltest du dein Problem umskalieren.
-
goran schrieb:
-2.16840434497101e-19 ist das Ergebnis welches näher an der Wahrheit liegt.
LOL. Schnapp dir mal Zettel und Stift und staune! Das exakte Ergebnis ist 0!
Matlab hat nicht die Wahrheit gepachtet.
-
Die alte x87 FPU rechnet mit 80 Bit Genauigkeit. Wenn du für x86_64 kompilierst, dann werden die entsprechenden SSE-Befehle genommen, die mit 64 Bit Genauigkeit rechnen. Wenn du optimierst, dann rechnet gcc das schon zur Kompilierzeit zusammen - ebenfalls mit 64 Bit Genauigkeit. Deswegen bekommst du das "andere" Ergbnis nur bei x86 und ausgeschalteten Optimierungen.
-3.01755e-20 liegt übrigens näher am realen Ergebnis.
-
Auf 0 bin ich auch gekommen nachdem ich den Algorithmus numerisch etwas besser gemacht habe:
int main() { double w = -0.00161579; double rho = -3.23158e-05; double Igrad = 0.0004; const double gamma = 0.02; w = w - rho * (gamma / Igrad); //division zuerst durchführen, da hier gamma bzw Igrad näher aneinander liegen als Igrad und (rho*gamma) std::cout << w << std::endl; }
-
bestatigt: exakt null kommt raus, wie seppj bereits angemerkt hat.
-
w = w - rho * gamma / Igrad;
für solche vorschulenaufgaben muss man also heutzutage matlab bemühen, interessant ... rofl, scnr.

-
Könnte gut sein, das die verschiedenen compiler es in unterschiedlicher Reihenfolge rechnen, und man deshalb andere Ergebnisse bekommt. Kann da jemand den asm output vergleichen? Bin mit Assembler leider nicht so bewandert.
-
KMT schrieb:
Könnte gut sein, das die verschiedenen compiler es in unterschiedlicher Reihenfolge rechnen
Siehe
Athar schrieb:
Die alte x87 FPU rechnet mit 80 Bit Genauigkeit. Wenn du für x86_64 kompilierst, dann werden die entsprechenden SSE-Befehle genommen, die mit 64 Bit Genauigkeit rechnen. Wenn du optimierst, dann rechnet gcc das schon zur Kompilierzeit zusammen - ebenfalls mit 64 Bit Genauigkeit. Deswegen bekommst du das "andere" Ergbnis nur bei x86 und ausgeschalteten Optimierungen.
-3.01755e-20 liegt übrigens näher am realen Ergebnis.
-
Ah ok, übersehen.