cast verursacht Zahlenschwund



  • Hallo miteinander,

    Aufgabe war es eine Funktion zu erstellen welche Quersummen einer Ganzzahl ermittelt.
    Die Aufgabe wurde soweit gelöst, nur sitzen wir schon einige Zeit an einer Version eines Kollegen
    die die ganze Berechnung ein wenig umständlicher löst.(Das komplette Programm mit passender Ausgabe hänge ich noch mal hinten dran.)

    Ein Großteil der Zahlen wird richtig gerechnet, eine Außnahme stellt aber die 5555 dar.

    Das Problem liegt hierbei in der letzten Schleife der Funktion qsum().

    for (z;z>0;z--)   //multipliziert die Zahl in jedem Durchlauf mit 10 und
        {                 //zieht davon den integer ab.
            t++;          //Beispiel: Die Zahl steht bei 9.9184, so werden 9 
                          //abgezogen und die Zahl wird auf 0.9184 gesetzt.
    
            cout<<"+++++"<<t<<". Durchlauf: +++++\n\n";
            b=b*10;
    	cout<<b<<"=b\n\n";
    
    	cout<<c<<"=c\n\n";
            c=(b); 		  //c= integer von b
    	cout<<c<<"=c\n\n";
    
            a=a+c;
            cout<<a<<"=a\n\n";
    
            b=b-c;  	   //integer von b abziehen, siehe Beispiel oben
            cout<<b<<"=b\n\n";
    
    		c=0;
    
        }
    

    Im 4. Durchlauf der Ausgabe wird aus unerfindlichen Gründen der vorher korrekt angezeigte Wert (-> b) während der Zuweisung verschluckt (-> c).

    +++++4. Durchlauf: +++++
    
    5=b      //
    
    0=c
    
    4=c      //
    
    19=a
    
    1=b
    
    Ergebnis: 19
    

    Aber als Ursache vermuten wir
    den cast.

    c=(b); 		  //c= integer von b
    

    Als Lösung hatten wir schon mehrere Varianten der Cast's in betracht gezogen ( int(b), static_cast<int>(b) ), sowie ein
    Aufrunden des Wertes. Aber Erfolg hatten wir damit nicht.

    Vielleicht hat noch jemand eine Idee wie wir an die Sache rangehen können bzw welches Phänomen hinter diesem Problem steckt.

    Danke schon mal für die Aufmerksamkeit.
    Gruß

    #include <iostream>
    #include <conio.h>
    #include <math.h>
    
    using namespace std;
    
    //Deklaration
    int qsum (int);
    
    //Hauptprogramm
    int main ()
    {
        int a;
        cout<<"Zahl, deren Quersumme berechnet werden soll: ";cin>>a;
        cout<<"Ergebnis: "<<qsum (a);
        getch ();
        return 0;   
    }
    
    //Definiton
    int qsum (int a)
    {
        double b;
        int z=1,c,t=0;
        b=a;
    
        while (a>9) 	  //Schleife ermittelt Anzahl der Stellen
        {
              a=a/10;
              z++; 		  //Eingegebene Zahl hat z-Stellen
        }
    
        a=0; 	      //a= Zähler der Quersumme, t= Schleifenzähler, b= eingegebene Zahl 
        b=b/(pow(10,z));  //bringt die Zahl auf 0.xxxxx....
    
        for (z;z>0;z--)   //multipliziert die Zahl in jedem Durchlauf mit 10 und
        {                 //zieht davon den integer ab.
            t++;          //Beispiel: Die Zahl steht bei 9.9184, so werden 9 
                          //abgezogen und die Zahl wird auf 0.9184 gesetzt.
    
            cout<<"+++++"<<t<<". Durchlauf: +++++\n\n";
            b=b*10;
    	cout<<b<<"=b\n\n";
    
    	cout<<c<<"=c\n\n";
            c=(b); 		  //c= integer von b
    	cout<<c<<"=c\n\n";
    
            a=a+c;
            cout<<a<<"=a\n\n";
    
            b=b-c;  	   //integer von b abziehen, siehe Beispiel oben
            cout<<b<<"=b\n\n";
    
    		c=0;
    
        }   
        return a;
    }
    
    Zahl, deren Quersumme berechnet werden soll: 5555
    +++++1. Durchlauf: +++++
    
    5.555=b
    
    2293576=c
    
    5=c
    
    5=a
    
    0.555=b
    
    +++++2. Durchlauf: +++++
    
    5.55=b
    
    0=c
    
    5=c
    
    10=a
    
    0.55=b
    
    +++++3. Durchlauf: +++++
    
    5.5=b
    
    0=c
    
    5=c
    
    15=a
    
    0.5=b
    
    +++++4. Durchlauf: +++++
    
    5=b
    
    0=c
    
    4=c
    
    19=a
    
    1=b
    
    Ergebnis: 19
    


  • Sieht so aus als würde ein interner Rundungsfehler auftreten.

    b=b/(pow(10,z));
    

    5555 / 10 ^ 4 sollte 0,5555 sein
    scheinbar macht er aber
    0,55549999999999999999
    daraus

    cout rundet das intern selber (oder erkennt den Fehler und berichtigt ihn) -> somit sieht man es nicht 😉

    Im vierten Durchlauf geschieht dann aber folgendes:

    c = (b);  // von double 4,9999999 nach int = 4
    
    c = Round (b)  // hier richtige Rundungsfunktion einsetzen ;)
    

    sollte das Problem beheben.

    Keros


Anmelden zum Antworten