Zahl -> Bit ausgabe
-
int bit_zahl; cout << "Zahl eingeben:"; cin >> bit_zahl; for (int i = 1; i <= sizeof(int)*(sizeof(bit_zahl)); ++i){ if (bit_zahl >> 0 == 1 ) cout << 1 << " "; else if (bit_zahl >> 0 == 0 ) cout << 0 << " "; }
Ich möchte die eingegebene Zahl binär ausgeben lassen doch dieses programm funktioniert nicht richtig woran könnte es liegen?
-
Mal in den Code reinkommentiert:
Aoki_san schrieb:
int bit_zahl; // Wieso heisst die Variable bit_zahl? Zahlenbasis wird nicht gespeichert cout << "Zahl eingeben:"; cin >> bit_zahl; for (int i = 1; i <= sizeof(int)*(sizeof(bit_zahl)); ++i){ //sizeof(int) = 4; sizeof(bit_zahl) = 4 (da int); 4 * 4 = 16; du iterierst also im Intervall [1, 16], ein int hat aber meist nicht 16 Bits if (bit_zahl >> 0 == 1 ) // x >> 0 ist gleich wie x; die Zeile lautet also: if(bit_zahl == 1) und damit ist nicht nur die letzte Stelle gemeint cout << 1 << " "; else if (bit_zahl >> 0 == 0 ) // dasselbe: else if(bit_zahl == 0) cout << 0 << " "; }
Was du möchtest:
unsigned Zahl; // Mal vorzeichenlos, denn Vorzeichen und shiften hat so seine Eigenheiten cout << "Zahl eingeben: "; cin >> Zahl; // besser [0, x) also halboffenes Intervall, das brauchst du später bei Arrays etc. dauernd, daher schonmal angewöhnen for(int i = 0; i < sizeof(Zahl) * 8; ++i) // sizeof(Zahl) = Anzahl Bytes in Zahl; 8 steht für 8 Bits / Byte { if(/* TODO: höchstes Bit */ != 0) cout << '1'; else cout << '0'; /* TODO: Zahl so verändern, damit das zweithöchste Bit im nächsten Schleifendurchgang das höchste ist */ }
Deine Aufgaben habe ich mal mit TODO gekennzeichnet. Tipp: Du brauchst dafür Bitmasken, die du in C++ mit dem Bitweise-Und-Operator realisieren kannst, den du ja vorhin kennen gelernt hast.
Kommentare für andere Leser:
Statt 8 kann / sollte manCHAR_BIT
oder besser gleich die C++-Variante nehmen, das ist aber jetzt noch zu viel.
Ist mir auch bewusst, dassint
nicht optimal als Typ für die Laufvariable ist, aber auch noch egal für den Moment.
-
Das scheint mir unlogisch zu sein da ich ja eigentlich nicht auf die einzelnen Bits zugreife weil ich es nur gewohnt bin es mit dem index operator durchzuführen
ich hab mit trzdm gedacht es vllt so zu versuchen:
if (/* TODO: höchstes Bit */ (Zahl& INT_MAX ) != 0)
Also da MAX_INT = 1111 1111 1111 1111 1111 1111 ...... ist kann ich es damit ja vergleichen = (Zahl) (...) (...) (....) (...) und wenn da eine zahl größer als 0 mitbei ist wird 1 ausgegeben nun weiß ich aber nicht ob er alle bits checkt oder nur das erste
ich hab mit gedacht mit dem shiftoperator auf das nächste bit zu zeigen ( >> 0 <- 0 weil z.B. 10^0 = 1 ergibt) also das ganze dann von links nach rechts auszugeben
nun wollte ich fragen ob ich total daneben liege oder ob es schon in die richtige richtung geht wenn ja habt ihr vllt noch einen weiteren tipp für mich??
-
Aoki_san schrieb:
Das scheint mir unlogisch zu sein da ich ja eigentlich nicht auf die einzelnen Bits zugreife weil ich es nur gewohnt bin es mit dem index operator durchzuführen
Mit dem Subscript-Operator greift man aber nicht auf die Bits zu. Und wenn du die einzelnen Bits einer Zahl ausgeben möchtest, dann musst du ja auf die Bits zugreifen.
Aoki_san schrieb:
ich hab mit trzdm gedacht es vllt so zu versuchen:
if (/* TODO: höchstes Bit */ (Zahl& INT_MAX ) != 0)
Aufgepasst! Was ist der Typ von
Zahl
? Und was ist der Typ vonINT_MAX
? (Hinweis: Der NameINT_MAX
deutet es schon ganz subtil an)
Aoki_san schrieb:
Also da MAX_INT = 1111 1111 1111 1111 1111 1111 ......
In's Messer gerannt! Dem ist eben nicht so.
INT_MAX
ist normalerweise0111 1111 ...
. Siehe Zweierkomplement. Daher habe ich auchunsigned
stattint
vorgeschlagen, das ist für den Anfang einfacher.Aoki_san schrieb:
Also da MAX_INT = 1111 1111 1111 1111 1111 1111 ...... ist kann ich es damit ja vergleichen = (Zahl) (...) (...) (....) (...) und wenn da eine zahl größer als 0 mitbei ist wird 1 ausgegeben nun weiß ich aber nicht ob er alle bits checkt oder nur das erste
Wenn es nur das erste prüfen würde, dann wäre würde
1 != 0
zufalse
ausgewertet werden, denn das erste Bit bei 1 ist gleich wie bei 0. Also wird bei!=
die gesamte Zahl verglichen. Und daher reicht diese1111...
-Maske nicht. Wir müssen effektiv auf das vorderste Bit (MSB) zugreifen. Und genau das musst du noch irgendwie bewerkstelligen.
Tipp 2:(Zahl & xy)
war schon ein guter Ansatz. Damit ist die Sache mit dem Maskieren an sich schon gegessen. Fehlt nur noch die richtige Maske.Aoki_san schrieb:
ich hab mit gedacht mit dem shiftoperator auf das nächste bit zu zeigen ( >> 0 <- 0 weil z.B. 10^0 = 1 ergibt) also das ganze dann von links nach rechts auszugeben
Da hast du vermutlich etwas bzgl. dem Shift-Operator falsch verstanden.
Also, was geschieht beim Shiften?
Genau! Es werden die Bits einzeln verschoben. Mit Zehnerpotenzen oder dergleichen hat das erstmal nichts am Hut. Ein Beispiel:0001 << 1 == 0010 // Also um eine Binärstelle in die Pfeilrichtung verschoben 0010 << 2 == 1000 // Hier dasselbe aber um zwei Stellen 1000 >> 3 == 0001 // Ja, in die andere Richtung geht's auch! 0001 << 0 == 0001 // Um 0 Stellen verschoben, da geschieht logischerweise nicht viel... 0110 << 1 = 1100 // Für mehrere gesetzte Bits geht's natürlich auch 1111 << 1 = 1110 // Eine 1 rausgeshiftet und von hinten kommt dennoch eine 0 nach 1111 >> 1 = 0111 // Und es kommt auch von der anderen Seite eine 0 nach. Was raus geht bleibt draussen und rein kommen tun immer nur 0en (gilt nur für unsigned!) 0001 << -1 = Boom // Um eine negative Anzahl Stellen shiften ist verboten 0001 >> -1 = Boom // Dito 0001 << 99 = Boom (höchstwahrscheinlich) // Wenn ein Datentyp n Bits hat, dann darfst du nie um n oder mehr Stellen shiften, das ist auch verboten
Aoki_san schrieb:
nun wollte ich fragen ob ich total daneben liege oder ob es schon in die richtige richtung geht wenn ja habt ihr vllt noch einen weiteren tipp für mich??
Ach, ist doch ganz okay. Wenn es Fragen gibt, dann frage. Wenn ich etwas undeutlich erkläre, dann sag es mir. Ich kann (leider) keine Gedanken lesen.
-
Wie verzweifelt ich doch bin ._.
:for (int i = 0; i < sizeof(Zahl) * 8; ++i) // sizeof(Zahl) = Anzahl Bytes in Zahl; 8 steht für 8 Bits / Byte { if (/* TODO: höchstes Bit */ (Zahl& UINT_MAX) != 0) cout << '1'; else cout << '0'; /* TODO: Zahl so verändern, damit das zweithöchste Bit im nächsten Schleifendurchgang das höchste ist */ }
wenn ich möchte das das zweite bit als höchstes steht muss ich das erste bit runter setzen oder nicht?
also bit 1 auf 0 setzen oder nicht?
Oder denke ich wieder in die Falsche richtung?
-
Aoki_san schrieb:
if (/* TODO: höchstes Bit */ (Zahl& UINT_MAX) != 0)
Also jetzt steht x für ein unbestimmtes Bit, entweder 0 oder 1:
iEnd = sizeof(Zahl) * 8; |<- iEnd ->| Zahl: xxxx ... xxxx UINT_MAX: 1111 ... 1111 &: xxxx ... xxxx
Wie du siehst erreichst du damit nicht viel. Wenn man nur Einsen in der Maske hat dann bleibt die Eingabe unverändert. Wir wollen aber nur das höchste Bit haben, alle anderen sollen 0 sein. Du kannst dir das auch als eine Art Gleichungssystem aufschreiben:
Zahl: xxxx ... xxxx Maske: ???? ... ???? &: x000 ... 0000
Immer überlegen, was mit was verknüpft was ergibt bei der Bitweise-Und-Operation. Wahrheitstabelle kann helfen wenn du noch nicht so sicher bist.
Aoki_san schrieb:
wenn ich möchte das das zweite bit als höchstes steht muss ich das erste bit runter setzen oder nicht?
Formalitäten (wie den Code den ich dir gegeben habe) nehme ich gern ab. Denkarbeit nicht. Denn dabei lernt man ja effektiv 'was. Analog beim Raten. Wenn man rät, dann funktioniert das Programm vielleicht irgendwann, aber man hat dabei nichts gelernt. Das kann kaum das Ziel sein (damit möchte ich dir nicht unterstellen, dass du rätst; ich äussere es eher mit einem prophylaktischen Gedanken).
Also du überlegst dir folgendes:
Wir haben eine Schleife. Diese durchlaufen wir genau so oft wie unsere Zahl Bits hat. Dabei ist bei jedem Durchlauf ein anderes Bit oben. Kann dann jemals ein Bit zwei Mal zuoberst sein?
Oder noch viel einfacher:
Wir geben eine Zahl in der binären Schreibweise aus. Werden gewisse Bits mehrfach ausgegeben?Aoki_san schrieb:
also bit 1 auf 0 setzen oder nicht?
In der Programmierung zählt man immer von 0 weg. Das solltest du dir angewöhnen. Auch damit du weniger Kommunikationsschwiergkeiten mit anderen Leuten hast. Bit 0 ist das niederwertigste Bit (LSB). Und vorhin hast du ja herausgefunden, was links hinzugefügt wird, wenn man nach rechts schiebt (und umgekehrt). Da musst du nichts manuell hinzufügen. Und auch wenn, wieso solltest du das tun wollen?
Also ich skizziere dir mal unser Vorhaben, vielleicht wird es dir dann klarer:
Zahl = 1010 i = 0 Konsolenausgabe: Schleifendurchgang: Ist i noch im gültigen Bereich? Ja -> Fortfahren Ist das höchste Bit von Zahl gesetzt? Ja -> 1 ausgeben Zweithöchstes Bit an die Stelle vom höchsten schieben Zahl = 0100 i = 1 Konsolenausgabe: 1 Schleifendurchgang: Ist i noch im gültigen Bereich? Ja -> Fortfahren Ist das höchste Bit von Zahl gesetzt? Nein -> 0 ausgeben Zweithöchstes Bit an die Stelle vom höchsten schieben Zahl = 1000 i = 2 Konsolenausgabe: 10 Schleifendurchgang: Ist i noch im gültigen Bereich? Ja -> Fortfahren Ist das höchste Bit von Zahl gesetzt? Ja -> 1 ausgeben Zweithöchstes Bit an die Stelle vom höchsten schieben Zahl = 0000 i = 3 Konsolenausgabe: 101 Schleifendurchgang: Ist i noch im gültigen Bereich? Ja -> Fortfahren Ist das höchste Bit von Zahl gesetzt? Nein -> 0 ausgeben Zweithöchstes Bit an die Stelle vom höchsten schieben Zahl = 0000 i = 4 Konsolenausgabe: 1010 (sieht so aus wie Zahl zu Beginn) Schleifendurchgang: Ist i noch im gültigen Bereich? Nein -> Ende Gelände
-
So, nach langen Ueberlegungen habe ich es raus gefunden. Ich habe zwar einige male nach Aehnlichen Themen gegoogelt um raus zu finden, ob ich etwas vergessen habe zu machen, bzw. um zu schauen ob ich richtig verstanden habe. Doch jetzt kann ich mir erklären wie ich genau vorgehen muss und was ich machen muss, deshalb gehe ich davon aus, dass ich es verstanden habe.(\(.)/) Ich muss nur noch zusehen, dass ich den ersten Bit nach jedem Schleifendurchlauf um einen nach links verschieben kann.
Ich verwende bei der ersten if Anweisung mittlerweile folgenden befehl:
if(Zahl& (1 << 32) != 0)
-
Wenn du eine 1 um 32 Stellen nach links verschiebst, an der wievielten Stelle steht die 1 dann hinterher? Um es leichter zu machen: Wenn du eine 1 um 2 Stellen nach links verschiebst, an welcher Stelle steht sie dann?
Ich glaube, da ist auch noch irgendwo eine Frage in deinem letzten Beitrag, aber mangels Satzzeichen kann ich sie nicht erkennen.
-
32 Stellen:
1000 0000 0000 0000 0000 0000 0000 0000
2 stellen
100Durchlauf 1:
0000 0000 0000 0000 0000 0000 0000 0001
1000 0000 0000 0000 0000 0000 0000 0000Durchlauf 2:
0000 0000 0000 0000 0000 0000 0000 0010
1000 0000 0000 0000 0000 0000 0000 0000Usw also so habe ich es mir zumindest gedacht
-
Oh, ok. Ich bearbeite kurz den Text, damit es besser lesbar für euch ist.
Edit: Fertig bearbeitetAoki_san schrieb:
So, nach langen Ueberlegungen habe ich es raus gefunden. Ich habe zwar einige male nach Aehnlichen Themen gegoogelt um raus zu finden, ob ich etwas vergessen habe zu machen, bzw. um zu schauen ob ich richtig verstanden habe. Doch jetzt kann ich mir erklären wie ich genau vorgehen muss und was ich machen muss, deshalb gehe ich davon aus, dass ich es verstanden habe.(\(.)/) Ich muss nur noch zusehen, dass ich den ersten Bit nach jedem Schleifendurchlauf um einen nach links verschieben kann.
Ich verwende bei der ersten if Anweisung mittlerweile folgenden befehl:
if(Zahl& (1 << 32) != 0)
-
Aoki_san schrieb:
32 Stellen:
1000 0000 0000 0000 0000 0000 0000 0000
2 stellen
100Interessante Art zu zählen.
-
Aoki_san schrieb:
32 Stellen:
1000 0000 0000 0000 0000 0000 0000 0000
2 stellen
100Fällt dir da gar nicht auf? Ok, dann eben explizit: Gib mal zu jeder Zahl zwischen 2 und 32 an, wo die 1 landet, wenn du sie um diese Anzahl stellen nach links verschiebst.
-
Achsoo oops
sorry
-
Das heißt aber das ich nur die 32 in 1 umändern muss
Aber wieso funktioniert das programm immer noch nicht korrekt? :///#include <iostream> using namespace std; int main() { // your code goes here unsigned Zahl = 1; for (int i = 0; i < 32; ++i){ if (Zahl&(1 << 1) != 0) cout << 1 << " "; else cout << 0 << " "; Zahl = Zahl << 1; } return 0; }
-
if (Zahl&(Zahl << 0) != 0)
Rätst du bloß?
edit: Jetzt hast du editiert und daraus(1 << 1)
gemacht. Was meine Vermutung mit dem Raten nochmals untermauert. Was ist denn1 << 1
deiner Meinung nach?Das heißt aber das ich nur die 32 in 1 umändern muss
Ich kann deine Gedanken überhaupt nicht mehr nachvollziehen. Welche Schlüsse hast du denn aus meiner Bemerkung zur 32 gezogen, die dich zu obigem Zitat bringen?
-
Ne habe gerade gesehen das ich die falsche ideone seite offen hatte
(Habe mehrere codes auspeobiert da keines zum richtigen ergebnis führte)
Die eigentliche if anweisung war if(Zahl&(1 << 1)!=0);
-
Nunja wenn ich auf 1 stehe und jedesmal 32 weiter nach linkslaufe überschreite ich die eigentliche grenze nach einem durchlauf oder nicht? Deshalb hab ich es auf 1 gesenkt
-
Aoki_san schrieb:
(Habe mehrere codes auspeobiert da keines zum richtigen ergebnis führte)
Also liege ich richtig mit der Annahme, dass du gerade nur wild herum probierst.
Zitat eines früheren Moderators:
c.rackwitz schrieb:
Wenn du selber Code schreibst, musst du ihn auch verstehen. Code ist kein Haufen von wahllos zusammengeschmissenen Buchstaben und Zeichen, Code ist Logik pur. Du musst genau wissen, warum du wo und welches Zeichen setzt.
Was ist denn (1 << 1)? Was willst du an der Stelle haben? Hast du überhaupt verstanden, was & und << machen? Was ist die Idee an diesem Code? asfdlol hat sie ja eigentlich schon recht schön und ausfühlrich erklärt, aber du scheinst bloß blind seinen Ansatz genommen zu haben, ohne ihn zu verstehen (möglicherweise nicht einmal versucht, ihn zu verstehen?) und versuchst nun verzweifelt zu raten, was an die Stellen kommt, die asfdlol bewusst frei gelassen hat.
-
Nein ich rate nicht ich denke und probiere es aus.
Ich habe mir gedacht das die 1 ja bei 32 bit so dargestellt wird :
0000 0000 0000 0000 0000 000 0 0000 0001
Und die Zahl die eingegeben wurde ja
Auch 0000 0000 0000 0000 0000 0000 0000 0001
Ist und durch Zahl&(1 << 1) der wert der hinter (1 << 1) steckt binär umgewandelt wird danach werden die binär zahlen nach jeder schleife verglichen da in den klammer 1 << steht wird auch nah jeder schleife die binärzahl um eines verschoben der wert der in der mask gespeichert wird kann damit nur 0 oder 1 sein wenn sich also mask(wert 1) und mask (zahl) treffen sollten wird eine eins ausgegeben und je länger ich darüber nachdenke wird mir klar das ich es richtig gemacht habe nur wird bei dieser schleife nicht vorne sondern hinten angefangen und deshalb steht der letzte wert vorne und nicht hinten hmm dann muss ich wohl schauen wie ich das ändern kann ich hoffe ihr könnt mir noch folgen
-
Oh man, I pack it not.
Ein waschechter Infinite Monkey Programmer.