Array lässt Werte verschwinden



  • Hallo Community,

    Bevor ich euch mit meinem Problem belästige, stell ich mich kurz vor.

    Ich bin absoulter Informatik-Neuling und habe mich für einen Fernkurs der SGD entschieden. Ich habe jetzt die ersten 2 Monate hinter mir und wurde bisher in grundlegende Funktionsweise von C++ eingewiesen. Schleifen, Funktionen und Felder.

    Nun bin ich auf ein Problem gestoßen, für das ich einfach keine Lösung finde.

    "Die Aufgabe lautete: Erstellen sie ein C++ Programm, das Dualzahlen in Dezimalzahlen umwandeln kann."

    Hier mein Listing:

    #include <iostream>

    using namespace std;

    int main()
    {
    // Das Feld zum Einlesen und die Variablen
    int rest[16];
    int eingabe;
    int ergebnis=0;

    // Die Ziffern im Feld einlesen
    do
    {

    cout<<" Bitte eine Dualzahl eingeben, die in eine Dezimalzahl umgerechnet werden soll( max. 65535):"<< endl;
    cin>> eingabe;
    } while(eingabe > 1111111111111111);

    for( int i=0;i<16;i++)
    {rest[i]=eingabe%10;
    eingabe=eingabe/10;

    }

    // Feldwerte mit den 2er Potenzen multiplizieren

    rest[15]=rest[15]*32768;
    rest[14]=rest[14]*16384;
    rest[13]=rest[13]*8192;
    rest[12]=rest[12]*4096;
    rest[11]=rest[11]*2048;
    rest[10]=rest[10]*1024;
    rest[9]=rest[9]*512;
    rest[8]=rest[8]*256;
    rest[7]=rest[7]*128;
    rest[6]=rest[6]*64;
    rest[5]=rest[5]*32;
    rest[4]=rest[4]*16;
    rest[3]=rest[3]*8;
    rest[2]=rest[2]*4;
    rest[1]=rest[1]*2;
    rest[0]=rest[0]*1;

    // Addition und Ausgabe

    for(int i=0;i<16;i++)
    {ergebnis=ergebnis+rest[i];

    }

    cout<<ergebnis;

    return 0;
    }

    Nun zu dem Problem: Ist die "eingabe" länger als 12 Ziffern, kommt als Ergebnis immer 2559 raus 😡
    Ich finde den Grund hierfür einfach nicht. Die Feldelemente 12-15 scheinen auch nicht mit der ausgelesenen Ziffer versehen zu sein, denn wenn ich mir diese Elemente einzeln ausgeben lasse, steht da immer eine 0 drin, obwohl eine 1 ausgelesen wurde. Auch hier verstehe ich nicht warum.

    Des Weiteren habe ich noch keine sinnvolle Bedingung gefunden um eine Eingabefehler abzufangen. Am liebsten wäre es mir, wenn die Schleife anspringt, sobald ein Wert !=0 oder 1 eingegeben wird. Egal welche Variante ich hier bisher probiert habe, es hat nicht funktioniert.

    Für eure Hilfe danke ich euch schon mal im Voraus.



  • Welchen Wertebereich hat denn ein int bei dir?



  • Das Programm ergibt so keinen Sinn.
    Mittels

    cin >> eingabe;
    

    wird eine Dezimalzahl eingelesen!!!
    Um eine Dualzahl einlesen zu wollen, wäre es das beste, diese als String einzulesen und dann die Umrechnung durchzuführen.

    PS: Auch

    do
    {
      // ...
    }
    while(eingabe > 1111111111111111);
    

    ist daher nicht sinnvoll! :p



  • Hallo OdinS0n!

    Denn du den Datentyp "int" verwendest, dann ist der gewöhnlich 4 Byte lang.
    Darin kannst du Dezimalzahlen bis zu einer Größe von +- 2147483647 darstellen.
    Zählst du die Stellen dieser Zahl, kommst du auf 10.

    In deinem Programm ist die Dezimalzahl aber 16 Stellen lang.

    Nimmst du statt dessen "long int", dann ist der Typ 8 Byte lang.

    Der geht von
    -9,223,372,036,854,775,807
    bis
    9,223,372,036,854,775,807
    Ist also 19 Stellen lang.

    Daher habe ich dein Programm nur ein klein wenig angepasst:

    #include <iostream>
    
    //using namespace std; //Wenn statt dessen z.B. std::cout verwendet wird
    
    int main()
    {
    // Das Feld zum Einlesen und die Variablen
    long int rest[16], eingabe;
    long int ergebnis=0;
    
    // Die Ziffern im Feld einlesen
    
    std::cout<<" Bitte eine Dualzahl eingeben, die in eine Dezimalzahl umgerechnet werden soll( max. 65535):" << std::endl;
    cin >> eingabe;
    
    std::cout << "Laenge der Variable Typ int: " << (sizeof(long int)) << "\nIhre Eingabe war: " << eingabe << "\nBeginne Auswertung: " << std::endl;
    
    for( int i=0;i<16;i++)
    {
     rest[i]=eingabe%10;
     std::cout << "rest[" << i << "]=" << rest[i] << "  eingabe=" << eingabe;
     eingabe=eingabe/10;
     std::cout << "   Eingabe=" << eingabe<< std::endl;
    }
    
    // Feldwerte mit den 2er Potenzen multiplizieren
    rest[15]=rest[15]*32768;
    rest[14]=rest[14]*16384;
    rest[13]=rest[13]*8192;
    rest[12]=rest[12]*4096;
    rest[11]=rest[11]*2048;
    rest[10]=rest[10]*1024;
    rest[9]=rest[9]*512;
    rest[8]=rest[8]*256;
    rest[7]=rest[7]*128;
    rest[6]=rest[6]*64;
    rest[5]=rest[5]*32;
    rest[4]=rest[4]*16;
    rest[3]=rest[3]*8;
    rest[2]=rest[2]*4;
    rest[1]=rest[1]*2;
    rest[0]=rest[0]*1;
    
    // Addition und Ausgabe
    
    for(int i=0;i<16;i++)
    {ergebnis=ergebnis+rest[i];
    
    }
    
    std::cout<<ergebnis;
    
    return 0;
    }
    


  • Das ist aber immer noch der falsche Weg.
    Da dezimal, dual, oder Hexadezimal nur andere Darstellungen von Werten sind, sollte man auch die Form einer Darstellung benutzen: über Zeichen.

    Also Zahl als String einlesen und dann umwandeln.

    Da braucht man dann auch keine Zweierpotenzen kennen und es geht auch ganz einfach für jede Basis von 2 bis 10 (darüber kommen dann Buchstaben und das macht es etwas schwieriger)

    wert  = 0;
    basis = 2;
    für i von 0 bis Stringende
      // hier fehlt noch der Test auf gültiges Zeichen
      wert = wert * basis + (string[i]-'0')
    

    Und das funktioniert auch, wenn man weniger als 16 Stellen eingibt.



  • Erstmal danke für die Antworten. Ich werde erstmal die Version mit long int probieren, da dieser Weg wahrs. auch der gewünschte des Lerninsitut ist.
    Der Lösungsweg über string klingt auch logisch, allerdings weiß ich nicht wie ich string zu int konvertiere oder umgekehrt. Wie trenne ich die chars überhaupt vom string oder ist das gar nicht notwendig? Die Rechenoperatoren funktionieren nur mit int, float und co oder?



  • Eine Frage hab ich doch noch zu long int:
    1 Byte sind doch 8 Bits oder? Demnach kann ich mit 4 Bytes 32 Bits darstellen .Da ein Bit ein Zeichen darstellen kann, verstehe ich nicht warum der Datentyp int "zu klein" für die Darstellung ist.



  • Liest du überhaupt unsere Antworten?

    DirkB hat dir den Code für die String-Konvertierung hingeschrieben und rustyoldguy erklärt, warum 4 Byte nicht ausreichen.

    Du scheinst anscheinend wirklich nicht zu verstehen, was bei

    cin >> eingabe
    

    passiert, oder?

    Gib bei deinem Originalcode (also int eingabe) dort mal z.B. "1111111111111111" (also mehr als 10 Einsen) ein und laß es dir mittels

    cout << eingabe;
    

    danach wieder ausgeben!



  • Natürlich habe ich eure Beiträge gelesen und versuche sie zu verstehen.
    @rustyoldguy: danke. Verstehe jetzt was du mit der Größe der Zahl meinst.
    Aber trotz der Änderungen zu long int bekomme ich immer noch falsche Ergebnisse.
    Ich probiere später nochmal ein wenig rum.

    Wie gesagt, ich weiß nicht wie ich string /char zu int umwandle.



  • OdinS0n schrieb:

    Wie gesagt, ich weiß nicht wie ich string /char zu int umwandle.

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int unsignedIntPow(int base, unsigned exponent)
    {
       int result = 1;
    
       for(; exponent > 0; --exponent)
          result *= base;
    
       return result;
    }
    
    int main()
    {
       string test("11001");
       int result = 0;
       int maxInd = test.size() - 1;
    
       for(int i = maxInd; i >= 0; --i)
          if(test[i] == '1')
             result += unsignedIntPow(2, maxInd - i);
    
       cout << result;
    }
    


  • OdinS0n schrieb:

    Wie gesagt, ich weiß nicht wie ich string /char zu int umwandle.

    Das ist aber genau die Aufgabe von der Funktion.
    Dafür musst du aber erstmal gar nicht wissen, wie man einen kompletten String umwandelt, sondern nur, wie man ein Zifferzeichen wandelt.
    Und das ist sehr einfach. Du subtrahierst von dem Zeichen den Wert vom Zeichen '0': Zeichen-'0'

    Jetzt musst du nur noch an die einzelnen Zeichen ran kommen. Da verhält sich ein String wie ein Array

    wert  = 0;
    basis = 2;
    für i von 0 bis Stringende
      // hier fehlt noch der Test auf gültiges Zeichen
      wert = wert * basis + (string[i]-'0')
    

    eigentlich musst du für string dein Variablennamevom Eingabestring angeben und das für ... durch die entsprechende Schleife von C++ ersetzen.



  • OdinS0n schrieb:

    Da ein Bit ein Zeichen darstellen kann

    Informatik-Neuling? Die Vorlesungen beginnen im Oktober und im Januar bist du der Meinung, 1 Bit = 1 Zeichen? Wenn du nicht gerade in den Vorlesung ständig 3 Promille hattest, ist es für mich unverständlich, wie man zu so einer Annahme kommt...


Anmelden zum Antworten