C++ Eine kleine Verständnisfrage

AndrejPi

Cadet 1st Year
Registriert
Okt. 2018
Beiträge
9
Hallo zusammen,
ich habe hier ein kleines Programm welches eine Integerzahl in binär ausgibt.
C++:
#include<iostream>
using namespace std;


int main()
{
    int Zahl;
    int a1, a2, a3, a4, a5, a6, a7, a8;

    cout << "Geben Sie eine Zahl ein! \n";
    cin >> Zahl;
    a1 = 1 & Zahl;
    a2 = (2 & Zahl)>>1;
    a3 = (4 & Zahl)>>2;
    a4 = (8 & Zahl)>>3;
    a5 = (16 & Zahl)>>4;
    a6 = (32 & Zahl)>>5;
    a7 = (64 & Zahl)>>6;
    a8 = (128 & Zahl)>>7;

    cout <<"die Zahl in einzelnen Bits: "<< a8 << a7 << a6 << a5 << a4 << a3 << a2 << a1<< "\n";
    cout << "\n";
        system("pause");
        return 0;
}
Alles funktioniert super und ich verstehe 'fast' alles, hier kommt auch schon die Frage die ich habe. Ich kapiere nicht warum meine Zahl mit 1,2,4,8,16,32,64,128 maskiert/verundet (oder wie auch immer es richtig heisst) wird.
Den Vorgang bevor die Zahl an die low-bit Position geschoben wird verstehe ich irgendwie einfach nicht.

Wäre echt super wenn jemand das genau erklären könnte.
Danke schon einmal im Voraus.

Gruß Andrej
 
Betrachte die Zahl vor deiner Zahl als Binär-Zahl. Somit wird nur das einzelne Bit dieses Wertes "extrahiert" und dann geshiftet. 2 = 1 0 binär. 3 = 1 1 usw... 4 = 1 0 0 Dadurch wird immer eine 1 oder 0 ausgegeben.
sonst verschiebst du ja alle bits und du hättest nicht das gewünschte Ergebnis ( Hier eine 1 oder eine 0 ).
Hoffe das reicht zum Verstehen. Sonst einfach nochmal nachfragen.
Als Tip versuch mal jede Zahl Binär zu betrachten. Sowohl deine als auch die Berechnung dazu. Vielleicht hilft dir das? Denke wie ein PC :-)

Beispiele:
55 -> 0011 0111
&16 -> 0001 0000
= 0001 0000
oder :

55 -> 0011 0111
&8 -> 0000 1000
= 0000 0000
Jetzt musst du noch shiften. Oben kommt dann eine 1 raus und unten eine 0. Hilft das?
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: AndrejPi
Hallo,

Ich finde hier wird es sehr gut erklärt.


https://de.wikibooks.org/wiki/C++-Programmierung:_Operatoren#&_(bitweise_Und-Verknüpfung)

Du verknüpfst also einfach dein Bit und überprüfst ob es 0 oder 1 ist bei and(und &) ist nur 1&1=1, deshalb kommt an der richtigen stelle 1 bzw. 0 raus.

Der shift müsste die Position dann sein, wenn deine x&zahl zusammen passt wird es an diese position geschoben.
Ich hoffe ich konnte dir ein wenig helfen.

Du kannst es ja mal mit einem oder oder xor probieren. am besten mal Logik usw. anschauen.

achja und warum 1 2 4 8 16 usw. ist einfach die 2er potenz von Binär
2^6= 64 usw.


Ich bin kein c++ Profi, also falls es jemand besser erklärt trau der anderen Person ;)
 
  • Gefällt mir
Reaktionen: AndrejPi
@dracki @Nilson
Okay jetzt sehe ich es auch :rolleyes: hätte ich vllt. mal vorher machen sollen. Wenn man die Zahlen umwandelt kann man es direkt nachvollziehen.
@Bl4ckeagle
Logikgatter und das Manuelle rechnen ist bis jetzt kein Problem, kam halt nicht drauf warum gerade diese Zahlen :D.

Danke euch für die Hilfe, jetzt macht alles Sinn:)
 
Das verunden an der Stelle ist mit dezimalen Zahlen auch alles andere als schön und nicht gut lesbar. Besser wäre hier eine Schreibweise in hexadezimaler (0x), in binärer (0b) Form oder über Bitshifts. Mein Favorit wäre etwas in der Art (wobei das auch nicht optimal ist, aber es bleibt bei deinem Grundprnzip ;)):

a3 = ( (1<<2) & Zahl) >> 2;
 
  • Gefällt mir
Reaktionen: AndrejPi
@TopperHarley87
am besten wäre es natürlich mit arrays, aber wir sollten es zuerst ohne machen.
Aber ist das: a3 = ( (1<<2) & Zahl) >> 2; nicht komplizierter als das: a3 = (4 & Zahl)>>2:D
 
Eigentlich würde ich das ganze so machen:
C++:
#include <iostream>
#include <vector>

int main()
{
    unsigned int num;
    std::cout << "Please enter a non-negative integer between 0-255 (inclusive): ";
    std::cin >> num;
    
    std::vector<bool> bits(8);
    
    for(std::size_t i = 0; i < bits.size(); ++i)
        bits[bits.size()-1-i] = (num >> i) & 1;

    std::cout << "The bits (msb first) of '" << (num & 0xFF) << "' are: ";
    for(const auto& bit : bits)
        std::cout << bit;
    std::cout << std::endl;
    
    return 0;
}

Aber wenn du keine Arrays verwenden darfst, würde ich es so machen und finde das viel leserlicher:
C++:
#include <iostream>

int main()
{
    unsigned int num;
    std::cout << "Please enter a non-negative integer between 0-255 (inclusive): ";
    std::cin >> num;

    bool b0 = (num >> 0) & 1;
    bool b1 = (num >> 1) & 1;
    bool b2 = (num >> 2) & 1;
    bool b3 = (num >> 3) & 1;
    bool b4 = (num >> 4) & 1;
    bool b5 = (num >> 5) & 1;
    bool b6 = (num >> 6) & 1;
    bool b7 = (num >> 7) & 1;

    std::cout << "The bits (msb first) of '" << (num & 0xFF) << "' are: ";
    std::cout << b7 << b6 << b5 << b4 << b3 << b2 << b1 << b0 << std::endl;

    return 0;
}

Gruß
BlackMark
 
  • Gefällt mir
Reaktionen: AndrejPi
@BlackMark
Ich hatte ja nur eine Frage weil ich nicht ganz verstanden hatte warum etwas so gemacht wird xD. Aber deine Methode mit bool ist auch nicht übel.
 
@AndrejPi mir geht es nicht nur um bool, auch wenn bool viel mehr Sinn macht als int, sondern hauptsächlich um (num >> 3) & 1 statt (num & 8) >> 3, denn bei ersterem kann ich 3 einfach als index verwenden und das beliebig in einer Schleife machen (siehe meine Lösung mit Arrays), bei zweiterem muss ich erst herausfinden wie man von 3 auf 8 kommt um das dann generisch für ein beliebiges bit machen zu können.
@TopperHarley87 hat dir das zwar schon gezeigt, aber auch (num & (1 << 3)) >> 3 ist hässlich und schwer zu lesen, im Vergleich zu (num >> 3) & 1.
Um also deine Frage direkt zu beantworten, nein, die Form (num & (1 << i)) >> i ist nicht komplizierter, sondern generischer. Denn sie erlaubt es dir, das in einer Schleife zu machen, indem du i als index verwendest. Aber, noch besser, ist (num >> i) & 1, weil kürzer und leichter zu lesen und genauso mächtig.

Gruß
BlackMark
 
  • Gefällt mir
Reaktionen: dracki und TopperHarley87
Zurück
Oben