FEHLER beim Konvertieren? WARUM? (Sourcecode liegt bei!)



  • Hallo,
    Ich bin noch ein ziemlicher Neuling im programmieren mit C++ und habe nun ein problem mit untem aufgelisteten Sourcecode.

    Die Funktion addiereZeit() nimmt zwei "Minuten-Zeit-Werte" über cin entgegen, danach sollen die Werte in einen Minutenwert umgerechnet werden.

    Problem:
    Manchmal rechnet die Funktion richtig, manchmal falsch.

    Beispiele:

    4.11 + 4.50 = 9.01 // RICHTIG
    2.21 + 2.40 = 5.01 // RICHTIG
    2.11 + 2.50 = 5.00 // FALSCH, da 2.11 + 2.50 auch 5.01 Minuten 🙂

    Kann mir vielleicht einer sagen woran das liegt?
    Ich wäre euch sehr dankbar!

    gruß Caipi

    SOURCECODE:
    --------------------------------------------

    int addiereZeit()
    {
            float fAddiereMinuten1;
            float fAddiereMinuten2;
            int berechneMinutenVorKomma1;
            int berechneMinutenVorKomma2;
            float berechneMinutenNachKomma1;
            float berechneMinutenNachKomma2;
            float ergebnis;
            cout << "\tZeiten addieren:\n";
            cout << "\t" << linie << endl;
            cout << "\tBitte zwei Minutenwerte eingeben, welche addiert werden sollen:\n\n\t";
            cin >> fAddiereMinuten1;
            cout << "\t";
            cin >> fAddiereMinuten2;
    
            berechneMinutenVorKomma1 = (int) fAddiereMinuten1;
            berechneMinutenVorKomma2 = (int) fAddiereMinuten2;
    
            berechneMinutenNachKomma1 = fAddiereMinuten1 - berechneMinutenVorKomma1;
            berechneMinutenNachKomma2 = fAddiereMinuten2 - berechneMinutenVorKomma2;
    
            //cout << endl << berechneMinutenVorKomma1 << "  " << berechneMinutenVorKomma2 << endl;
            //cout << endl << berechneMinutenNachKomma1 << "  " << berechneMinutenNachKomma2 << endl;
    
            if(((berechneMinutenNachKomma1 + berechneMinutenNachKomma2) * 100) <= 59)
            {
                    ergebnis = berechneMinutenVorKomma1 + berechneMinutenVorKomma2;
                    ergebnis += berechneMinutenNachKomma1 + berechneMinutenNachKomma2;
            }
            else
            {
    
                    berechneMinutenVorKomma1 += ((berechneMinutenNachKomma1 + berechneMinutenNachKomma2) * 100) / 60;
                    float zwischenRechnung = (berechneMinutenNachKomma1 + berechneMinutenNachKomma2) * 100;
    
                    /////////////////////////////////////////////////////////////////////////
                    // FEHLERQUELLE ??
                    ///////////////////////////////////////////////////////////////////////
    
                    cout << endl << "Vor Konvertierung zu int:\t" << zwischenRechnung << endl;
                    cout << endl << "Nach Konvertierung zu int:\t" << (int)zwischenRechnung << endl;
                    zwischenRechnung = (int) zwischenRechnung % 60;
                    cout << endl << "Zwischenrechnung % 60:\t\t" << zwischenRechnung << endl; 
                    zwischenRechnung = zwischenRechnung / 100;
                    cout << endl << "Zwischenrechnung / 100:\t\t" << zwischenRechnung << endl;
    
                    ergebnis = berechneMinutenVorKomma1 + berechneMinutenVorKomma2 + zwischenRechnung;
    
                    ///////////////////////////////////////////////////////////////////////
    
            }
            cout << "\n\n\tErgebnis:\t" << setprecision(2) << fixed << ergebnis << endl << endl;
    
            return 0;
    }
    


  • es gibt werte, die man mit float nicht genau darstellen kann,liegt am binärsystem(vergleiche 1/9 im dezimalsystem)



  • otze schrieb:

    es gibt werte, die man mit float nicht genau darstellen kann,liegt am binärsystem(vergleiche 1/9 im dezimalsystem)

    Kannst du mir das vielleicht genauer erklären?
    Bin halt noch ein totaler Anfänger 🙂

    Caipi



  • es gibt werte, die sich binär nicht genau darstellen lassen(wie zb auch der bruch 10/3).
    nun, genau solche ungenauen bruchwerte gibts auch im binärsystem, und soweit ich mich erinner war 0,01 sowas?(bitte schlagen wenn ich mich irre).



  • Zwei weitere dumme Fragen 🙂

    Was hat das mit dem Code in der Funktion addiereZeit() zu tun?
    Wie kann ich das Problem umgehen?

    Caipi



  • Caipi schrieb:

    Was hat das mit dem Code in der Funktion addiereZeit() zu tun?
    Wie kann ich das Problem umgehen?

    Das hat ganz einfach deshalb was damit zu tun weil du float benutzt.

    Mit double könnte das Problem gelöst sein.



  • Ändere einfach mal die entsprechende Zeile zu

    cout << endl << "Vor Konvertierung zu int:\t" << setprecision(8) <<  zwischenRechnung << endl;
    

    Du wirst sehen, dass zwischenRechnung kleiner als 61 wegen der genannten Effekte ist. Die Konvertierung nach int ist ein Abrunden und kein Runden im normalen Sinne, so dass daraus 60 wird.



  • Hallo an alle, vielen Dank für euer Feedback!

    Demnach müsste ich ja einfach nur die Variable zwischenRechnung aufrunden, bevor ich sie nach int konvertiere, oder??

    Wie heißt denn die Funktion zum aufrunden ? (round()?)

    Caipi



  • korrekt runden kannst du, indem du zum float Wert 0.5 dazuaddierst.
    also z.B.

    float x=3.9f;
    
    int gerundet_x=static_cast<int> (x+0.5f);
    //Funktioniert auch im grenzfall
    
    float y=3.4f;
    
    int gerundet_y=static_cast<int> (y+0.5f)	//ergibt 3.9f, und da alle nachkommastellen gestrichen werden, kommt 3 raus.
    

Anmelden zum Antworten