2013-02-11 6 views
8

verschieben Warum wennjava Bitoperationen >>>

int x = -1 // binary: 11111111111111111111111111111111 
x = x >>> 31; 

wir 00000000000000000000000000000001

haben, aber wenn

int x = -1 
x = x >>> 32; 

wir 11111111111111111111111111111111 haben (wieder -1)

aber nicht 00000000000000000000000000000000 ?

+1

Da Verschiebungen in Java immer modulo die Länge des verschobenen Wertes sind. –

+1

Das ist wirklich gut zu wissen, wenn man bedenkt, dass es aus mathematischer Sicht einfach falsch ist! –

Antwort

13

Von Section 15.19 of JLS:

Falls der begünstigt Typ des linken Operanden int ist, werden nur die fünf niedrigstwertigen Bits des rechten Operanden werden als die Verschiebung Abstand verwendet. Es ist so, als ob der rechte Operand einem bitweisen logischen UND-Operator & (§15.22.1) mit dem Maskenwert 0x1f (0b11111) unterzogen würde. Die tatsächlich genutzte Verschiebestrecke liegt daher immer im Bereich inklusive.

Schwerpunkt meiner. Also:

x >>> n 

entspricht:

x >>> n & 0x1f // or x >>> n % 32 

So x >>> 32-x >>> 32 & 0x1f < == entspricht>x >>> 0 == x.

So ist die Daumenregel ist, wenn Sie eine Zahl um ein Vielfaches von 32 verschieben (int ist 32 bits), erhalten Sie den gleichen Wert zurück.

+0

+1, Perfekt (Y) –

+0

IMHO, das ist eine wirklich schlechte Wahl! Mathematisch sind die beiden absolut NICHT äquivalent. Nun, wenn das eine Operation ** rotieren ** war, und nicht eine Verschiebung, ok. Aber dieses? Wer hat das erfunden? –

+0

Wie soll ich >>> schalten um eine 0 zu bekommen? – ses

2

Bei der Bit-Shift-Operation werden nur die untersten 5 Bits des rechten Operanden berücksichtigt. Seit 32 === 0 // mod 32 ist das Ergebnis keine Verschiebung.

0

einen ganzen Tag damit verbracht meinen Kopf darüber, warum ein langer l brechen = i < < 32 seltsam benommen, schrieb dann einige grundlegenden Tests, hatte den WTF Moment, und chnged dann zu lange l = (long) i < < 32 es funktioniert.

Meine einzige Ergänzung zu Rohits Antwort ist der Grund, warum das so ist. Von IA-32 Intel® Architecture Software Developer's Manual 3:

Der 8086 maskiert die Anzahl der Verschiebungen nicht. Alle anderen IA-32-Prozessoren (beginnend mit dem Intel 286-Prozessor) maskieren jedoch die Verschiebezahl auf 5 Bits, was zu einer maximalen Zählung von 31 führt. Diese Maskierung wird in allen Betriebsmodi (einschließlich des virtuellen 8086-Modus) durchgeführt Reduziere die maximale Ausführungszeit der Befehle