Bit-Abfrage
-
Hallo, ich hatte eine kleine Aufgabe wo ich übrprüfen sollte ob ein Bit gesetzt ist oder eben halt nicht. Eigentlich nichts Besonderes. Leider bin ich kolosal daran gescheitert und musste feststellen dass es an meinem Abfrage-Konstrukt lag. Habe jetzt ein Beispiel genohmen und stelle die Frage dort. Ist genau so bei mir passiert. Also erstes das Quellcode-Beispiel welches funktioniert.
cout << "Eingabe einer Zahl: "; int zahl { 0 }; cin >> zahl; int anzahlDerBytes { sizeof zahl }; int anzahlDerBits { 8 * anzahlDerBytes }; cout << " binär : "; for (int k = anzahlDerBits - 1; k >= 0; --k) { if ((zahl & (1 << k))) { cout << '1'; } else { cout << '0'; } } cout << '\n';
Soweit ist Alles klar und nachvollziehbar. Jetzt der Code mit einer kleinen Änderung. Wieso funktioniert DAS nicht mehr?
FEHLERCODE:cout << "Eingabe einer Zahl: "; int zahl { 0 }; cin >> zahl; int anzahlDerBytes { sizeof zahl }; int anzahlDerBits { 8 * anzahlDerBytes }; cout << " binär : "; for (int k = anzahlDerBits - 1; k >= 0; --k) { if ((zahl & (1 << k)) == true) { // oder auch == 1 //geänderte Zeile cout << '1'; } else { cout << '0'; } } cout << '\n';
Die Überprüfung auf FALSE klappt wieder, ich muss dann nur das COUT tauschen. Die Frage bleibt aber trotzdem: WIESO klappt das mit der Abfrage auf TRUE nicht?
-
Weil
(zahl & (1 << k))
nur 1 ist, wenn k==0 und das LSB von zahl gesetzt ist.
(zahl>>k) & 1
-
HMMM danke für die INFO. Leider checke ich gerade garnichts. Werde mir das wohl noch einmal genauer ansehen müssen mit dem LSB. Trotzdem vielen Danke, vielleicht raff ich es bald noch
Deswegen haben wohl die ganzen ungerade Zahlen bei der Eingabe eine "1" als ausgabe gebracht. Verstehe es immer noch nicht aber das kommt bestimmt noch.
-
@uuuguuug sagte in Bit-Abfrage:
if ((zahl & (1 << k)) == true) {
wird zu
if ((zahl & (1 << k)) == static_cast<int>(true)) {
da bei einem Vergleich beide Seiten auf die gleiche Größe gebracht werden. Du vergleichst also eine Zahl mit einer anderen statt auf wahr/falsch zu testen.
Schreibe nie
if( irgendwas == true )
.
-
Danke für die Erklärung, denke dass mir die Erläuterung weiterhelfen wird.
-
Bei
(zahl & (1 << k)
kommt nicht nur0
oder1
als Ergebnis heraus, sondern durch die Maskierung0
oder .
Und durch den expliziten Vergleich auftrue
(oder1
) wird eben nur beik = 0
die Bedingung wahr.
-
@manni66 Hallo, wenn ich nichts falsch gemacht habe hat deine Änderung leider nichts bezweckt...
Eine Frage habe ich immer noch bevor ich mir weiter mein Gehirn malträtiere. Wieso funktioniert das Beispiel ganz am Anfang des Beitrage noch wo nicht explizit auf TRUE oder FALSE geprüft wird?lg der UuugUuug
-
@uuuguuug sagte in Bit-Abfrage:
@manni66 Hallo, wenn ich nichts falsch gemacht habe hat deine Änderung leider nichts bezweckt...
Das ist keine Änderung, sondern das, was der Compiler implizit macht. Das kann nicht funktionieren.
Wenn du unbedingt den Vergleich auf true willst (lass es!) dann musst du selber nach bool casten:
if (static_cast<bool>(zahl & (1 << k)) == true) {
-
Danke dir auch noch einmal, das hilft auch wieder ein Stück weiter. Und NEIN ich will das nicht unbeding TUN sondern einfach verstehen was da so abgeht....
Das Bespiel hat jetzt endlich auch funktioniert. Jetzt wirklich die allerallerletze Frage. Wieso sollte ich es nicht expilzit so machen wie du es mir gezeigt hast, was ja auch funktioniert, da es der Comiler ja genau so implizit zu tun scheint?.
War definitiv die letzte Frage.
-
Die generelle Abfrage
if (x)
entspricht einem Vergleich auf!= 0
, d.h.if (x != 0)
. Und daher funktioniert es bei dir, wenn du auffalse
(bzw.0
) testest und die Anweisungen vertauschst (da imelse
-Fall dann "ungleich Null" gilt).
-
Ganz kurz:
Die Frage, ob etwas ungleich 0 ist, ist nicht dasselbe wie ob etwas gleich 1 ist.
Zum Beispiel ist 2 ungleich 0, aber 2 ist nicht gleich 1.if (zahl)
vergleicht auf ungleich 0, ist also dasselbe wieif (zahl != 0)
.
if (zahl == true)
wandelttrue
in eine Zahl um (nämlich 1) und vergleicht dann, es wird also zuif (zahl == 1)
.Jetzt endlich klar?
-
@uuuguuug sagte in Bit-Abfrage:
Wieso sollte ich es nicht expilzit so machen wie du es mir gezeigt hast, was ja auch funktioniert, da es der Comiler ja genau so implizit zu tun scheint?.
Wenn du damit meinst warum du nicht
if (static_cast<bool>(zahl & (1 << k)))
schreiben solltest? Weil das kein Mensch lesen will. Schreibif (zahl & (1 << k))
. Oder wenn du es etwas "expliziter" haben willst:if ((zahl & (1 << k)) != 0)
.Die Variante mit dem
static_cast<bool>
ist zwar korrekt und funktioniert, aber total unüblich und daher verwirrend bzw. behindert den Lesefluss. In der Software-Entwicklung ist es wie auch bei anderen Ingenieurtätigkeiten wichtig sich an übliche Muster zu halten. Weil Konstruktionen die das nicht tun für erfahrene Ingenieure schwerer zu "lesen" sind.
-
@uuuguuug sagte in Bit-Abfrage:
Wieso sollte ich es nicht expilzit so machen wie du es mir gezeigt hast, was ja auch funktioniert, da es der Comiler ja genau so implizit zu tun scheint?.
Welche zusätzliche Information liefert dir das ganze Geschwätz, dass du dann schreiben musst? Hättest du den Versuch mit
== true
gar nicht erst unternommen, hättest du viel Zeit gespart.Siehe auch Don’t add redundant == or != to conditions
-
ich wusste es einfach nicht besser und die Abfrage auf TRUE war für mich soweit logisch aber wie gesehen falsch. Ich denke dass Thema hier kann geschlossen werde.
Gruss der UuugUuug
-
@uuuguuug sagte in Bit-Abfrage:
ich wusste es einfach nicht besser und die Abfrage auf TRUE war für mich soweit logisch
Im Prinzip hast du recht, aber es ist halt C