Warum bricht die Schleife nicht ab?



  • Hallo zusammen,

    die Frage steht oben. Theoretisch müsste die Schleife doch bei 2.0 abbrechen, oder? Ich komme einfach nicht darauf, warum sie das nicht tut.

    #include <stdio.h>
    int main(void) {
    
    float x = 1.0f;
    
    printf ("    X   | X * X\n");
    printf (" -------+-------\n");
    
    while(x != 2.0f) {
            printf (" %6.2f | %6.2f\n", x, x * x);
            x += 0.1f;
            }
    system ("PAUSE");
    }
    

    Und noch eine Frage: Das kleine "f" hinter den float-Zahlen ist doch unnötig, oder? Ist ja doppelt gemoppelt.

    Danke & LG
    SOA



  • StudentOhneAhnung schrieb:

    Theoretisch müsste die Schleife doch bei 2.0 abbrechen, oder?

    Korrekt. Sie bricht nicht ab, weil der Wert 2.0f nie erreicht wird, was daran liegt, dass die reelle Zahl 0,1 nicht exakt als Gleitkommazahl darstellbar ist, was wiederum daran liegt, dass 0,1 im Binärsystem periodisch ist. Das ist ungefähr so, wie wenn du 1/3 als Dezimalbruch 0,33 darstellst und dich wunderst, warum 0,33 + 0,33 + 0,33 nicht 1 ergibt.

    Generell musst du bei Gleitkommazahlen immer mit Rundungsproblemen irgendeiner Form rechnen. Falls dich die Details interessieren, google nach "what every computer scientist should know about floating point arithmetic".

    Und noch eine Frage: Das kleine "f" hinter den float-Zahlen ist doch unnötig, oder? Ist ja doppelt gemoppelt.

    Nein, ohne das f sind die Konstanten vom Typ double. Wenn du float x = 1.0 schreibst, wird die double-Konstante nach float umgewandelt, weshalb das f nicht unbedingt immer notwendig ist, aber im Zweifelsfall kannst du damit sicherstellen, dass deine Konstanten wirklich floats sind.


  • Mod

    Bashar schrieb:

    Und noch eine Frage: Das kleine "f" hinter den float-Zahlen ist doch unnötig, oder? Ist ja doppelt gemoppelt.

    Nein, ohne das f sind die Konstanten vom Typ double. Wenn du float x = 1.0 schreibst, wird die double-Konstante nach float umgewandelt, weshalb das f nicht unbedingt immer notwendig ist, aber im Zweifelsfall kannst du damit sicherstellen, dass deine Konstanten wirklich floats sind.

    Um mal zu erklären, wann das wirklich relevant wird: Das spielt beispielsweise eine Rolle bei Vergleichen.

    float f = 0.1;
    printf("%i %i", f == 0.1, f == 0.1f);  // Ausgabe: "0 1"
    

    Wobei absolute Vergleiche bei Fließkommazahlen ohnehin mit Vorsicht zu genießen sind, wie man, unter anderem, bei Bashars Stichwort nachlesen kann.



  • Vielen Dank euch beiden!


Log in to reply