演算子>>
符号付き右シフトは、すべてのビットを指定された回数右にシフトします。重要:>>
は、シフト後の左端のビットに左端の符号ビット(Most Significant Bit MSB)を埋めます。これは、符号拡張と呼ばれ、には、右にシフトすると負の符号が保持されます。
以下
これは(1バイトのために)どのように動作するかを示すために例と私の概略図である。
例:2の補数形式で
i = -5 >> 3; shift bits right three time
ファイブは1111 1011
メモリ表現であります:
MSB
+----+----+----+---+---+---+---+---+
| 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
+----+----+----+---+---+---+---+---+
7 6 5 4 3 2 1 0
^This seventh, the left most bit is SIGN bit
そして、以下は、>>
の仕組みですか?あなたは-5 >> 3
this 3 bits are shifted
out and loss
MSB (___________)
+----+----+----+---+---+---+---+---+
| 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
+----+----+----+---+---+---+---+---+
| \ \
| ------------| ----------|
| | |
▼ ▼ ▼
+----+----+----+---+---+---+---+---+
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
+----+----+----+---+---+---+---+---+
(______________)
The sign is
propagated
通告を行うと:一番左の3ビットがあるため、各シフト符号ビットが保存されるに一つであり、各ビットは右すぎです。私は書いたこの3ビットはすべて符号(データではない)のために、符号はに伝搬されます。
また、右の3つの右シフトのために、ほとんどの3ビットが失われます。
右の2つの矢印の間のビットは、-5
の前のビットから公開されています。
正の数の例も書いてもいいと思います。次の例では、5 >> 3
で、5は、1つのバイトが、私はサインはそう左端の3ゼロビットに署名する予定です、伝播され書き込みを再び参照してください0000 0101
this 3 bits are shifted
out and loss
MSB (___________)
+----+----+----+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
+----+----+----+---+---+---+---+---+
| \ \
| ------------| ----------|
| | |
▼ ▼ ▼
+----+----+----+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+----+----+----+---+---+---+---+---+
(______________)
The sign is
propagated
です。
これはオペレータです>>
符号付き右シフトは、左オペランドの符号を保持します。
[解答]
あなたのコードでは、あなたはとても右手最も31
ビットを緩め、結果は実際に-1
大きさがあるすべてのビット1
でいる>>
演算子を使用して31
回右へ-15
を移します。
このように、-1 >> n
はステートメントではないことに気づいていますか?
私は1つのi = -1 >> n
を行う場合には、Javaコンパイラによってi = -1
に最適化されなければならないと考えているが、それは別の問題である
次に、より多くの右シフト演算は、符号なし呼ば>>>
利用可能であるJavaのいずれかで知って興味深いものになるだろう右シフト。論理的に動作し、シフト操作ごとに左からゼロを埋めます。だから、右シフトごとに符号なし右シフト>>>
演算子を負の数と正の数の両方に使用すると、常に最も左の位置にゼロビットが得られます。
例:以下
i = -5 >>> 3; Unsigned shift bits right three time
とは、どのように表現-5 >>> 3
作品を実証し、私の図でありますか?
this 3 bits are shifted
out and loss
MSB (___________)
+----+----+----+---+---+---+---+---+
| 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
+----+----+----+---+---+---+---+---+
| \ \
| ------------| ----------|
| | |
▼ ▼ ▼
+----+----+----+---+---+---+---+---+
| 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
+----+----+----+---+---+---+---+---+
(______________)
These zeros
are inserted
そして、あなたは気づくことができます。この時間は、私はその伝播の符号ビットが、実際に>>>
オペレータインサートゼロを書き込むわけではありません。したがって、>>>
は、論理右シフトを行う代わりに符号を保持しません。
私の知識では、符号なしの右シフトはVDU(グラフィックスプログラミング)では役に立ちますが、私はそれを使用していませんでしたが、過去にはどこかでそれを読んでいました。
私はこれを読むことをお勧めします:Difference between >>> and >>:>>
は右に算術シフト、>>>
は論理的に右にシフトします。
編集:
符号なし右に関するいくつかの興味深いオペレータ>>>
オペレータをシフトします。
符号なし右シフト演算>>>
、その右オペランドで指定されたビットの数でゼロ0
拡張と右シフトの左オペランドである純粋な値を生成します。
>>
と同じように、オペレータ>>>
も例外をスローしません。
符号なし右シフト演算子の各オペランドの型は、整数データ型である必要があります。そうでない場合、コンパイル時エラーが発生します。
>>>
演算子は、そのオペランドで型変換を実行できます。算術バイナリ演算子とは異なり、各オペランドは独立して変換されます。オペランドの型がbyte、short、またはcharの場合、そのオペランドは演算子の値が計算される前にintに変換されます。
符号なし右シフト演算子によって生成される値の型は、その左のオペランドの型です。LEFT_OPERAND >>> RHIGT_OPERAND
左オペランドの変換タイプがintである場合、右オペランドの値のみ5つの最下位ビットは、シフト距離として使用されます。 (2 = 32ビット= INTにおけるビットの数である)
だから、シフト距離は、ここ31
介し範囲0であり、r >>> s
した値と同じです。
s==0 ? r : (r >> s) & ~(-1<<(32-s))
左オペランドの型は、右オペランドの値のわずか6つの最下位ビットは、シフト距離として使用され、長い場合。( = 64ビットであります=長いビット数ここ)
、r >>> s
した値は、次のように同じである。
s==0 ? r : (r >> s) & ~(-1<<(64-s))
興味深いリファレンス:[Chapter 4] 4.7 Shift Operators
ところで、あなたは '>>> -1'を使うことができ、' int'型と 'long'型で動作します。 –