Forum: PC-Programmierung Bitmanipulation Rechtsschieben


von Le H. (beks)


Lesenswert?

Hallo,

ich habe eine Variable von Datentyp unsigned char. Ich möchte jetzt die 
1 komplett durch das Byte schieben.

Sodass mit den nächsten Rechtsschiebungen die folgenden Ergebnisse 
entstehen.

0b01000000
0b00100000
0b00010000
0b00001000
0b00000100
0b00000010
0b00000001

Soweit sollte es über den Ausdruck funktionieren.
1
unsigned char test = 0b10000000;
2
while(1){
3
    test>>=1;
4
}

Was passiert allerdings dann mit der nächsten Rechtsschiebung, wenn die 
Variable test=0x01 ist?

Wie lasse ich die 1 dann wieder im Bit 7 setzen und den ganzen Ablauf 
von vorn beginnen?
1
unsigned char test = 0b10000000;
2
while(1){
3
    test>>=1;
4
    if(test==0x01)test=0b10000000;
5
}

: Bearbeitet durch User
von g457 (Gast)


Lesenswert?

> Was passiert allerdings dann mit der nächsten Rechtsschiebung, wenn die
> Variable test=0x01 ist?

Die 1 purzelt rechts raus.

> Wie lasse ich die 1 dann wieder im Bit 7 setzen und den ganzen Ablauf
> von vorn beginnen?

Wieder eine 1 links einfädeln?

von Le H. (beks)


Lesenswert?

g457 schrieb:
> Wieder eine 1 links einfädeln?

Gibt es da eine besser Lösung als mit meiner If Bedingung?

von (prx) A. K. (prx)


Lesenswert?

uint8_t test = 0x80;
while (1)
  test = (test >> 1) | (test << 7);
Nicht zwingend besser, aber zumindest anders.

: Bearbeitet durch User
von Frank (Gast)


Lesenswert?

Gibt's in ASM evtl 2 unterschiedliche Befehle für Shift und Rotate?

von Sebastian V. (sebi_s)


Lesenswert?

Was du möchtest ist im Grunde eine Rotation und kein Shift. Viele CPUs 
haben entsprechende Befehle dafür und bei dem Code von A.K. sollte jeder 
halbwegs anständige Compiler einen Rotate Befehl generieren wenn die 
Zielplatform das hergibt.

von (prx) A. K. (prx)


Lesenswert?

Frank schrieb:
> Gibt's in ASM evtl 2 unterschiedliche Befehle für Shift und Rotate?

Ja, nützt aber nicht unbedingt sehr viel, weil beispielsweise AVR kein 
8-Bit Rotate sondern nur einen 9-Bit Rotate hat (Register plus C Flag). 
Und ARM wiederum nur 32- und 33-Bit Rotate.

: Bearbeitet durch User
von Frank (Gast)


Lesenswert?

Ah,OK.
Danke für die info

von Le H. (beks)


Lesenswert?

Ich nutze einen ATMEGA und programmiere in C.

von Andreas R. (daybyter)


Lesenswert?

Die Idee mit den geschachtelten while-Schleifen find ich schon richtig, 
aber sollte man beim Testen nach dem Schieben nicht auf 0 testen?

unsigned char test = 0b10000000;
while(1){
    test>>=1;
    if(test==0x00)test=0b10000000;
}

oder if( ! test) { test=0b10000000; }

der Test auf 0 geht ja bei den meisten CPUs recht flott.

von BirgerT (Gast)


Lesenswert?

Was soll mit "test" passieren?
So wie gefragt, wird es der Compiler womöglich weg optimieren..
1
while(1){
2
  uint8_t test = 0b10000000;
3
  do {
4
     // hier muss etwas mit test gemacht werden
5
     // z.B. binaer_anzeige(test);
6
7
     test>>=1;
8
  }while(test !=0);
9
}

..aber das "while" ist auch nur eine "if"-Abfrage

von Peter II (Gast)


Lesenswert?

Andreas Rückert schrieb:
> der Test auf 0 geht ja bei den meisten CPUs recht flott.

der Test dauert genauso lange. Der Trick daran ist das bei den meisten 
Operation gleichzeitig der Vergleich auf 0 gemacht wird.
Damit kann man einfach das Ergebnis direkt verwenden.

Der Vergleich wird damit komplett eingespart.

von C C C (Gast)


Lesenswert?

Oder
1
while(1)
2
{    
3
  test = (test >>= 1) ? test : 0x80;
4
}

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.