Bitmanipulation
-
Ich muss folgende Aufgabe lösen:
Schreiben Sie ein C-Programm, das mithilfe der Operatoren zur Bitmanipulation die Binärdarstellung einer ganzen Zahl angibt. Zur besseren Lesbarkeit der Ausgabe soll nach 8 Stellen jeweils eine Leerstelle eingefügt werden.
Mein Code:
#include <stdio.h> #include <math.h> int main() { int rest[32], i, zahl; printf("Zahl eingeben: "); scanf("%d", &zahl); printf("\n"); for (i=0;i<32;i++) { rest[i] = zahl%2; zahl = zahl/2; } while (i>0) { i--; printf("%d", rest[i]); if(i % 8 == 0) { printf(" "); } } printf("\n"); return 0; }
Ich weiß jetzt nicht wie ich das mit Operatoren zur Bitmanipulation verändern kann. Vielleicht kann mir ja einer weiterhelfen.
-
test89 schrieb:
Ich weiß jetzt nicht wie ich das mit Operatoren zur Bitmanipulation verändern kann. Vielleicht kann mir ja einer weiterhelfen.
Führe mal an einigen Beispielen die Operationen
zahl%2
,zahl/2
undzahl%8
per Hand im Binärsystem durch, dann müsste dir was auffallen.
-
#include <stdio.h> //#include <math.h> // Wozu? Nur weil du "rechnest" brauchst du keine math.h int main() { unsigned zahl; // Negative Zahlen sind zwar auch nicht schwer, aber eine unnötige Verkomplizierung int i; printf("Zahl eingeben: "); scanf("%u", &zahl); printf("\n"); for (i = 31; i >= 0; --i) // Wozu erst speichern und dann ausgeben, wenn man gleich ausgeben kann? { printf("%i", (zahl >> i) & 1); // Schiebe i-te Stelle ganz nach rechts // und gucke, ob sie 1 oder 0 ist if ((32 - i) % 8 == 0) putchar(' '); } printf("\n"); return 0; }
edit: Ein paar Leerzeichen zur besseren Lesbarkeit eingefügt.
-
SeppJ schrieb:
#include <stdio.h> printf("%i", (zahl >> i) & 1); // Schiebe i-te Stelle ganz nach rechts // und gucke, ob sie 1 oder 0 ist
ja sry math.h nehm ich immer mit rein...
das ist ja jetzt die Zeile wo du Operatoren zur Bitmanipulation verwendest oder?
reicht das schon zur Beantwortung der Aufgabenstellung, weil es gibt ja noch mehr Operatoren und ich weiß nicht ob wir alle verwenden sollen...
gibt es noch ne Möglichkeit das mit mehr Operatoren zu lösen?
-
test89 schrieb:
gibt es noch ne Möglichkeit das mit mehr Operatoren zu lösen?
Klar, du kannst das immer weiter verkomplizieren, indem du unnötigen Schmarrn drum rum machst. Das war jetzt die am weitesten vereinfachte Version. Die ursprüngliche war:
(zahl & (1 << i)) >> i)
Aber wenn du sagst, dass du dies nimmst, dann kannst du auch:
(~(((zahl & (1 << i)) >> i) | 1) ^ -1U))
schreiben. Völlig sinnlos, aber benutzt jeden bitweisen Operator jeweils einmal.
Mach etwas in der Art wie ich es ursprünglich gemacht habe als richtige Antwort (und versteh es!) und dann kannst du den letzten Ausdruck noch als "clevere" Scherzantwort abgeben (musst du aber auch verstehen!). Wenn du Lust hast, kannst du noch die Operatorprioritäten nachschlagen und gegebenenfalls einige der Klammern entfernen. Dadurch sieht der Ausdruck dann noch kryptischer aus.
P.S.: Kurzer Erklärungsansatz:
-
1 << i erzeugt eine Maske mit genau einer 1 an der Stelle die wir betrachten
-
Dann wird diese Maske mit & auf die Zahl losgelassen. Ist an der Stelle eine 1, bekommen wir diese 1, ansonsten 0.
-
Dann wird die 1 bzw. 0 mit >> i an die hinterste Stelle verschoben, so dass wir tatsächlich den Wert 1 haben und nicht 2 hoch i.
-
Der Rest sind geschickte Bitmanipulationen, die sich gegenseitig aufheben:
-
| 1: ist eine Identität
-
^ -1U: Wenn man etwas mit einer 1 ver-XOR-t, dann dreht man die Binärziffern genau um, aus 1 wird 0 und umgekehrt. Die Zahl -1U (also unsigned Zahl -1 = größter darstellbarer unsigned Wert) ist gerade die Zahl, die an jeder Binärstelle eine 1 hat.
-
Das obige XOR hat also gerade alle Ziffern umgedreht, durch das ~ macht dies also gerade wieder rückgängig.
-
-
alles klar danke für deine Hilfe...