私はインターネットからのクラムノートを使用してSCJP試験の練習をしています。
私のメモによると、>>
演算子は右シフトで署名され、符号ビットは左から取り込まれることになっています。一方、左シフト演算子<<
は符号ビットを保持することになっています。
ただし、遊んでみると、<<
演算子を使用して符号をシフトできます(つまり、Integer.MAX_VALUE << 1
は-2
に評価されますが、>>
演算子を使用して符号をシフトすることはできません。
私はここで何かを誤解しているに違いありませんが、何ですか?
「>>」はサインを保持しているのでサインされています。数値の2進表現の左端の桁をフィラーとして使用します。例えば:
| this value is used as a filler
11011011
>> 11101101
01010010
>> 00101001
">>>"はこの演算子の署名されていないバージョンです。常にゼロをフィラーとして使用します。
11011011
>>> 01101101
01010010
>>> 00101001
2進表現では、左端の桁が数値の符号を決定します。したがって、「1」の場合は負の値になり、「0」の場合は正の数になります。そのため、左端の数字をフィラーとして使用すると、記号を永続的に保つことができます。
シフトの背後にある考え方は、2の累乗で乗算および除算として機能できるということです(<< 1は* = 2に相当し、>> 2は/ = 4に相当します)。これが、符号付きバージョンのシフトが存在する理由です。ただし、符号なしシフトは必ずしもネガティブを保持しません。あなたが示唆するように、<<演算子は実際には符号を保持しません。それは単にあなたの例で起こります。 2,147,483,647で左シフトを試してください。それは前向きなままではありません。彼らがわざわざ「符号付き」の左シフトを行おうとしない理由は、数値が正から負(またはその逆)にシフトした場合、とにかく変数タイプの境界を超えたためです。