Fließkomma - Wie hole ich mehr Genauigkeit heraus?
-
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.
-
Seien folgende Werte gegeben: w = -0.00161579 rho = -3.23158e-05 Igrad = 0.0004 gamma = 0.02 Weiter sei angenommen y = rho * gamma. Dann folgt: y = -3.23158e-05 * 0,02 = -0,0000323158 * 0,02 = -0 - 0 - 00000646216 --------------- -0,000000646216 Weiter sei angenommen z = y / Igrad. Dann folgt: z = -0,000000646216 / 0,0004 = -0,000000646216 / (4/10000) = -0,000000646216 * (10000/4) = -0,00646216 / 4 = -0,00161554 Weiter sei angenommen A = w - rho * gamma / Igrad. Dann folgt: A = w - rho * gamma / Igrad = w - y / Igrad = w - z = -0,00161579 - -0,00161554 = -0,00161579 + 0,00161554 = -0,00000025 Damit folgt A != 0.Ferner gilt -0,00000025 < -2.16840434497101e-19 < -3.01755e-20.
Dann gilt auch der das -2.16840434497101e-19 näher an der Wahrheit liegt wenn -0,00000025 die Wahrheit ist.
-
Du hast dich bei y verrechnet.
-
goran schrieb:
Seien folgende Werte gegeben: w = -0.00161579 rho = -3.23158e-05 Igrad = 0.0004 gamma = 0.02 Weiter sei angenommen y = rho * gamma. Dann folgt: y = -3.23158e-05 * 0,02 = -0,0000323158 * 0,02 = -0 - 0 - 00000646216 --------------- -0,000000646216 Weiter sei angenommen z = y / Igrad. Dann folgt: z = -0,000000646216 / 0,0004 = -0,000000646216 / (4/10000) = -0,000000646216 * (10000/4) = -0,00646216 / 4 = -0,00161554 Weiter sei angenommen A = w - rho * gamma / Igrad. Dann folgt: A = w - rho * gamma / Igrad = w - y / Igrad = w - z = -0,00161579 - -0,00161554 = -0,00161579 + 0,00161554 = -0,00000025 Damit folgt A != 0.Ferner gilt -0,00000025 < -2.16840434497101e-19 < -3.01755e-20.
Dann gilt auch der das -2.16840434497101e-19 näher an der Wahrheit liegt wenn -0,00000025 die Wahrheit ist.