wurzelzieher problem



  • Hi leute ich bin gerade dabei einen wurzelzieher zu schreiben,
    doch wenn die variable teilen unter 0.5 ist dann wird die if abfrage garnicht aufgerufen hier der code:
    #include <iostream>

    using namespace std;

    int main(){
    double teilen = 0.1,test = 0,ergebniss = 0;

    double eingabe;
    cin>>eingabe;

    getchar();
    while (test == 0,eingabe > teilen * 2){
    ergebniss = eingabe/teilen;
    cout<<"teilen:"<<teilen<<endl; //nur zur hilfe

    cout<<"ergebniss: "<<ergebniss<<endl;//nur zur Hilfe

    if(teilen == ergebniss)
    {
    cout<<"Das ergebniss lautet: "<<teilen;
    test = 1;
    getchar();
    }
    teilen = teilen + 0.1;

    }
    getchar();
    return 0;
    }



  • Die Zahl 0.1 ist in Fließkommadarstellung nicht exakt darstellbar. Wenn du teiler = 0.1 schreibst, ist das in Wirklichkeit sowas wie 0.1000000000000000055511151231257827021181583404541015625. Diese Zahl ein paar mal aufaddieren ergibt also höchstens mit viel Glück (d.h. Rundungsfehler) irgendwann mal 0.5 (diese Zahl ist exakt darstellbar).

    BTW dass das nicht dein einziges Problem ist, ist dir hoffentlich klar.



  • Du solltest Fließkommazahlen nicht einfach direkt vergleichen.
    Das ist verpönt in der Programmierung.
    Lies dir das durch: http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/

    Außerdem bitte den Code in Codetags setzen und formatieren:

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        double teilen = 0.1,test = 0,ergebniss = 0;
    
        double eingabe;
        cin>>eingabe;
    
        getchar();
        while (test == 0,eingabe > teilen * 2)
        {
            ergebniss = eingabe/teilen;
            cout<<"teilen:"<<teilen<<endl; //nur zur hilfe
    
            cout<<"ergebniss: "<<ergebniss<<endl;//nur zur Hilfe
    
            if(teilen == ergebniss)
            {
                cout<<"Das ergebniss lautet: "<<teilen;
                test = 1;
                getchar();
            }
    
            teilen = teilen + 0.1;
        }
        getchar();
    }
    

    Mein Compiler gibt mir eine wichtige Warnung aus:

    GCC 4.8 schrieb:

    TEMP2.cxx|14|warning: left operand of comma operator has no effect [-Wunused-value]|

    Du wolltest wohl eher eine Konjunktion mit && , so verknüpft man nämlich logische Ausdrücke in C++.

    Außerdem benutzt du eine bescheuerte Methode, um die Schleife abzubrechen. Kennst du break ?

    Und ergebniss könntest du lokaler deklarieren, in der Schleife.



  • Dass das direkte Vergleichen von Gleitkommazahlen verpönt ist, ist eigentlich das falsche Argument – wichtig ist, dass es oft nicht so wie gedacht funktioniert. 😉
    Der Typ von ergebniss ist ein Grunddatentyp, daher ist es auch in Ordnung, es vor die Schleife zu ziehen, finde ich. Bei anderen Typen – insbesondere Klassentypen mit nichttrivialen Konstruktoren – kann die Position aber schon wichtig sein!
    Auf diese Weise die Schleife abzubrechen ist tatsächlich unschön, aber es gibt anscheinend einige Lehrer, die es so lehren (und fordern) …

    Übrigens, Ergebnis schreibt man üblicherweise genau so: ⤚⇒ Ergebnis ⇐⤙



  • Der Typ von ergebniss ist ein Grunddatentyp, daher ist es auch in Ordnung, es vor die Schleife zu ziehen, finde ich.

    Findest du? Macht aber keiner.

    aber es gibt anscheinend einige Lehrer, die es so lehren (und fordern) …

    Macht es das besser?
    Und wenn sie es fordern, dann ist Schluss mit lustig. Dann muss man eingreifen und diesen Blödsinn beenden. Es wird, und da wette ich drum', keinen einzigen C/C++/etc.-Prof, der break für Schleifen nicht kennt.


Anmelden zum Antworten