Warum endet Schleife mit 10.0?
-
Warum endet folgende Schleife mit 10?
Bei x+=0.5 klappt das, da endet sie bei 9.5 aber bei 0.1 nicht.
Kann es mit Rundung zu tun haben dass bei 100ter iteration x = 9.999999999
ist und deswegen reingeht aber in der ausgabe dann gerundet wird?#include <iostream> int main() { for ( double x = 0.0; x < 10.0; x += 0.1) std::cout << x << std::endl; }
-
GastXXD schrieb:
Kann es mit Rundung zu tun haben dass bei 100ter iteration x = 9.999999999
ist und deswegen reingeht aber in der ausgabe dann gerundet wird?Genau. 0.1 lässt sich als float nicht exakt darstellen.
-
Solche Algorithmen werden numerisch stabiler, wenn man sie etwas umschreibst:
int main() { double inc = 0.1; double max = 10.; std::size_t steps = max / inc - inc; for(std::size_t n = 0; n <= steps; ++n) { std::cout << inc * n << std::endl; } }so akkumulieren sich die Rundungsfehler nicht auf.
-
Daraus lernt man typischerweise zwei Dinge:
- Fließkommazahlen eignen sich nicht für Schleifenbedingungen (wegen der Rundungsfehler)
- a<b und a==b ist für Fließkommazahlen oft ne wacklige Angelegenheit. (gleicher Grund)
-
pumuckl schrieb:
Daraus lernt man typischerweise zwei Dinge:
- Fließkommazahlen eignen sich nicht für Schleifenbedingungen (wegen der Rundungsfehler)
- a<b und a==b ist für Fließkommazahlen oft ne wacklige Angelegenheit. (gleicher Grund)
Und wenn man noch ein wenig mehr Informationen möchte:
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
oder als PDF:
http://web.cse.msu.edu/~cse320/Documents/FloatingPoint.pdfOder noch etwas kürzer erklärt und einfach auf Vergleiche ausgerichtet:
http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/Oder als Witz:
http://xkcd.com/217/Grüssli