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.
Mittelscin >> 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...