Schleife bricht nicht korrekt ab.
-
Hi,
die Schleife in dem Programm soll bis einschlicßlich i=2 laufen.
Mein Problem ist nur, sie bricht immer vorher ab.
Nehme ich als Schrittweite 0.1 zählt er bis 1.9 hoch erreicht die 2 aber nicht mehr obwohl in der Bedingung steht i<=2.
Hat da jemand eine Idee?
Gruß
Chris#include <stdio.h> void main() { float schritt=0, y=0, i=0; printf("\nBitte geben Sie die Schrittweite ein: "); scanf("%f",&schritt); for (i=0;i<=2;i=i+schritt) {y=y+schritt; printf("\ni Wert: %f y Wert %f ",i,y); }; }
-
Das ist so nicht ohne weiteres möglich. Das Problem ist, daß 0,1 im Fließkommaformat des Rechners eine periodische Zahl ist; deshalb kommt es bei fortlaufender Addition zu Rundungsfehlern.
In Programmen, in denen es um Währungen, Geld oder ähnliches geht (Buchhaltungsprogramme zB), sollte man also Beträge nicht in diesem Format speichern.
-
also schleife scheint für mich korrekt zu sein
und ich habs noch getestet bei mir liefs wunderbar bis 2.0 durch
-
Das hängt mit der float-Genauigkeit zusammen.
Im letzten Schritt in der Schleife ist i nicht genau 1.9000000000,
sondern 1.9000002 oder so. Wenn Du jetzt nochmal 0.1 addierst, liegts Du schon über 2.0000000.Schleifen mit floats sind nicht so toll.
-
Hallo,
ich danke euch für die schnelle Antwort.
Demnach ist das Progi in der Theorie richtig, es scheitert aber an dem Rundungsfehler der float Variable im PC.Gibt es denn für das Problem einen einfachen "Workaround", so das es doch noch mit der Berechnung korrekt klappt?
Gruß
Chris
-
In Deinem konkreten Fall könntest Du die Schleife immer bis
i < 2
laufen lassen, und dann den Fall i == 2 gesondert behandeln.
Also etwa:for(int i = 0; i < 2; i += 0.1) { machwasmit(i); } machwasmit(2);
-
sorry, im Schleifenkopf darf es natürlich nicht int i heißen, sondern float i.
-
Demnach ist das Progi in der Theorie richtig
Nein ist es nicht!
es scheitert aber an dem Rundungsfehler der float Variable im PC.
Und zwar genau deswegen. Ein Test auf Gleichheit zwischen float/double Werten ist immer mit Vorsicht zu geniessen.
einen einfachen "Workaround"
Ja, siehe Belli.
-
for(int i = 0; i < 21; ++i) { machwasmit(i/10.); }