Forum: Mikrocontroller und Digitale Elektronik Verständtnis C-Code Bitmanipulation


von Sawyer M. (sawyer_ma)


Lesenswert?

Hallo alle zusammen,

ich verstehe gerade meinen eigenen Code in C nicht. Bei der 
Bitverschiebung können Bits eines Wertes nach links oder rechts 
verschoben werden. Gut das habe ich hier getan.

for(int x=0;x<10;x++){
  int c = x << 1;
  int b = c << 2;
  printf("%d\n",b);
}

Nach logischer Überlegung kam ich bei den Schritten auf folgendes 
Ergebnis:

1.) 0000 => C= 0000 => b = 0000 Ausgabe b = 0
2.) 0001 => C= 0010 => b = 1000 Ausgabe b = 8
3.) 0010 => C= 0100 => b = 0000 Ausgabe b = ?? Mein Ergebnis ist b = 1

usw.

die ganze Zahlenkette ist laut Programm 0, 8, 16, 24, 32, 40, 48, 56, 
64, 72 jedoch verstehe ich nicht warum??

Warum wird im 3 Schritt anstatt meiner berechneten 1 eine 16 
ausgegeben??
Was macht meine Schleife denn da??

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ein Integer hat nicht nur 4, sondern mindestens 16 oder gar 32 Bits...

von lambda (Gast)


Lesenswert?

Du gehst bei dir von lediglich 4 Bit für Int aus, Int ist aber deutlich 
größer, häufig 16 oder 32 Bit. Das heißt dein Überlauf kommt erst 
deutlich später.
x ist im dritten Schritt 2, damit ist c = 4 (x*2) und b = 16 (c*4).

von Frank (Gast)


Lesenswert?

Verschoben um 1 ist Multiplikation mit 2.
Sprich in c steht 0,2,4,8...
Verschoben um 2 ist Multiplikation mit 4.
Sprich in int b steht int c*4 oder x*8.
In Zahlen 0,8,16,24...

von Sina A. (sinapse)


Lesenswert?

aber selbst bei 4bit... wie kommst du zum schluss auf b=1?

von Sawyer M. (sawyer_ma)


Lesenswert?

Ok, ja das ist mir bekannt. Aber dann versteh ich nicht wieso mein 
zweiter Wert 8 ist?? Springt der immer in 4er Päckchen??

Also Anfangs 0000 wenn die voll sind werden weitere vier nullen 
angehangen also 0000 0000 usw.??

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Und zudem ist der << kein Rotationsoperator. Deshalb kommt nach dem 
Hinausschieben der 1 immer eine 00000000...00 heraus.

von Stefan F. (Gast)


Lesenswert?

3.)  x=0000000000000010
     c=0000000000000100
     b=0000000000010000   und das ist eben 16 in dezimal

Auch ich frage:
> wie kommst du zum schluss auf b=1?

Las ich raten: Du gehst davon aus, dass die Bits, die links heraus 
fallen, wieder von Rechts herein kommen. Das ist aber nicht der Fall. Du 
verwechselst hier das "schieben" mit "rotieren". Zum Rotieren von Bits 
hat allerdings IMHO die Sprache C keinen Operator. In Assembler würde 
das gehen.

von Sawyer M. (sawyer_ma)


Lesenswert?

Ach du Scheiße, vielen Dank. :D ich habe mich selbst ausgetrickst. Der 
Code sollte so heißen:

for(int x=0;x<10;x++){
  int c = x << 1;
  int b = c >> 2;
  printf("%d\n",b);
}

von Stefan F. (Gast)


Lesenswert?

> werden weitere vier nullen angehangen also 0000 0000 usw.??

Nein, "normale" Integer Variablen haben bei dieser Hardware-Architektur 
immer 16 Bits. Egal, welcher Wert da drin steht.

von Sawyer M. (sawyer_ma)


Lesenswert?

Vielen Dank für eure Hilfe. Leider war es ein klassischer Tippfehler. 
Trotzdem waren eure Antworten sehr hilfreich :)

von Stefan F. (Gast)


Lesenswert?

> Der Code sollte so heißen:

Was soll das werden?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Stefan U. schrieb:
> bei dieser Hardware-Architektur
Bei welcher?

von Markus F. (mfro)


Lesenswert?

Stefan U. schrieb:
> Zum Rotieren von Bits
> hat allerdings IMHO die Sprache C keinen Operator. In Assembler würde
> das gehen.

Das geht auch mit C. Ein einigermassen intelligenter Compiler erkennt, 
was Du haben willst. Mein (schon relativ betagter) m68k-gcc macht 
beispielsweise aus
1
uint32_t rol32(uint32_t x, uint32_t n)
2
{
3
    return (x << n) | (x >> (32 - n));
4
}

das da:
1
00000154 <_rol32>:
2
     154:  202f 0004        movel %sp@(4),%d0
3
     158:  222f 0008        movel %sp@(8),%d1
4
     15c:  e3b8             roll %d1,%d0
5
     15e:  4e75             rts

Wenn ich noch ein inline dazupacke, steht nur noch das roll da.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.