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 man CHAR_BIT oder besser gleich die C++-Variante nehmen, das ist aber jetzt noch zu viel.
    Ist mir auch bewusst, dass int 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 von INT_MAX ? (Hinweis: Der Name INT_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 normalerweise 0111 1111 ... . Siehe Zweierkomplement. Daher habe ich auch unsigned statt int 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 zu false ausgewertet werden, denn das erste Bit bei 1 ist gleich wie bei 0. Also wird bei != die gesamte Zahl verglichen. Und daher reicht diese 1111... -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 pro­phy­lak­tischen 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)


  • Mod

    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
    100

    Durchlauf 1:
    0000 0000 0000 0000 0000 0000 0000 0001
    1000 0000 0000 0000 0000 0000 0000 0000

    Durchlauf 2:
    0000 0000 0000 0000 0000 0000 0000 0010
    1000 0000 0000 0000 0000 0000 0000 0000

    Usw 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 bearbeitet

    Aoki_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
    100

    Interessante Art zu zählen.


  • Mod

    Aoki_san schrieb:

    32 Stellen:
    1000 0000 0000 0000 0000 0000 0000 0000
    2 stellen
    100

    🙄 Fä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;
    }
    

  • Mod

    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 denn 1 << 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


  • Mod

    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.


Anmelden zum Antworten