2015-01-24 12 views
6

Ich habe eine Hex-Nummer 0x8F (10001111 binär). Ich möchte diesen Wert nach rechts verschieben, also wäre der neue Wert 0xC7 (11000111). Ich habe versucht, mit:Wie man Bits in C++ richtig verschiebt?

unsigned char x = 0x8F; 
x=x>>1; 

aber anstelle von 0xC7 Ich habe 0x47? Irgendwelche Ideen, wie man das macht?

+4

Das erwartete Ergebnis ‚0xC7'is falsch - also signed Verschiebungen Implementierung definiert - aber Sie haben einen Wert ohne Vorzeichen hier –

+1

Wenn Sie es' ändern char' statt 'unsigned char' erhalten Sie das Verhalten, das Sie erwarten. Bei unsigned ist das Vorzeichenbit immer 0. Bei Vorzeichen werden Sie das höherwertige Bit umschalten, so dass negative Zahlen mit 1 anstelle von 0 gefüllt werden. – Charlie

+1

@Charlie: Solange "char" signiert ist und ein signed verschoben wird Wert gibt Vorzeichenerweiterung. Keine davon ist in C++ garantiert. –

Antwort

14

Rechtsverschiebung auf eine vorzeichenlose Menge wird neue Nullen eingeben, nicht Einsen.

Beachten Sie, dass die rechte Verschiebung nicht richtig ist Rotation. Um das zu tun, brauchen Sie

8

Das ist, weil was Sie wollen, ist ein "rechts drehen", nicht "rechts verschieben". Also müssen Sie für das niedrigste Bit "fallen" anpassen:

sollte den Trick tun.

[Und zumindest einige Compiler wird diese besondere Gruppe von Operationen erfassen und an die entsprechenden ror oder rol Anweisung konvertieren]

2

Rechtsverschiebung oder Linksverschiebung wird mit 0 s jeweils auf der linken oder auf der rechten Seite von füllen das Byte. Nach dem Verschieben müssen Sie OR mit dem richtigen Wert, um zu erhalten, was Sie erwarten.

x = (x >> 1); /* this is now 01000111 */ 
x = x | (0x80); /* now we get what we want */ 

Hier bin ich OR mit dem Byte 10000000 ing die 0x80 in 0xC7 resultierende ist.

machen es knapper, es wird:

x = (x >> 1) | (unsigned char)0x80; 
Verwandte Themen