24

次のJavaコードの抜粋を検討してください

byte b=(byte) 0xf1;
byte c=(byte)(b>>4);
byte d=(byte) (b>>>4);

出力:

c=0xff
d=0xff

期待される出力:

c=0x0f

どうやって?1111 0001 符号なし右シフト後の0000 1111バイナリ0x0fのb0xff として

4

6 に答える 6

43

int問題は、シフト操作が行われる前に、すべての引数が最初に昇格されることです。

byte b = (byte) 0xf1;

b署名されているため、値は -15 です。

byte c = (byte) (b >> 4);

bは最初に整数 に符号拡張され、次に にキャストされて-15 = 0xfffffff1右にシフトされ0xffffffff、 に切り捨てられます。0xffbyte

byte d = (byte) (b >>> 4);

bは最初に整数 に符号拡張され、次に にキャストされて-15 = 0xfffffff1右にシフトされ0x0fffffff、 に切り捨てられます。0xffbyte

(b & 0xff) >>> 4目的の効果を得るために行うことができます。

于 2010-10-16T09:18:02.013 に答える
5

シフト bする前に拡張された符号だと思います。int

したがって、これは期待どおりに機能する可能性があります。

(byte)((0x000000FF & b)>>4)
于 2010-10-16T09:13:48.450 に答える
1

Bitwise and Bit Shift Operatorsによると:

符号なし右シフト演算子 ">>>" はゼロを左端の位置にシフトしますが、">>" の後の左端の位置は符号拡張に依存します。

したがって、b >> 4変換1111 0001すると1111 1111(b は負なので、 が追加されます1) これは0xffです。

于 2010-10-16T09:13:48.963 に答える
0

Java は、代わりに 2 つの異なるシフト演算子を定義することによって、符号なし基本型の明示的なサポートを軽視しようとします。

質問は符号なし右シフトについて述べていますが、例では両方 (符号付きと符号なし) を行い、符号付きシフト (>>) の値を示しています。

あなたの計算は、符号なしシフト (>>>) に適しています。

于 2010-10-16T09:19:01.527 に答える
0

byte オペランドは、シフトの前に int に昇格されます。

https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19を参照してください。

単項数値昇格 (§5.6.1) は、各オペランドに対して個別に実行されます。(バイナリ数値昇格 (§5.6.2) はオペランドでは実行されません。)

そしてhttps://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.1

Otherwise, if the operand is of compile-time type byte, short, or char, it is promoted to a value of type int by a widening primitive conversion (§5.1.2).

于 2019-02-25T11:59:02.687 に答える