4


0

Javaで2つの短い値のビット単位ANDがint値になるのはなぜですか?
short permissions = 0755;
short requested = 0700;
short result = permissions & requested;

コンパイラエラーが発生します。

error possible loss of precision
found   : int
required: short

私がまったく間違っていない場合、バイナリANDの結果は最長のオペランドと同じです。 なぜ結果は整数ですか?

短めにキャストすると、パフォーマンスが低下しますか?

(short) permissions & requested

5 Answer


6


簡単な答え(ハァッ!)は、http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#170983 [バイナリ数値プロモーション]です。

_ * オペランドのいずれかが参照型の場合、ボックス化解除変換 (§5.1.8)が実行されます。 その後: * どちらかのオペランドがdouble型の場合、もう一方はdoubleに変換されます。 * それ以外の場合、一方のオペランドがfloat型の場合、他方は変換されます 浮かびます。 * それ以外の場合、一方のオペランドがlong型の場合、他方は変換されます 長い。 * それ以外の場合は、両方のオペランドがint型に変換されます。 _


3


_ 私がまったく間違っていない場合、バイナリANDの結果は最長のオペランドと同じです。 なぜ結果は整数ですか? _

Java言語仕様では、非長整数演算の結果は常にintであるとされているためです。 とにかく、32ビットCPUが内部でそのように動作するという事実を認めて、おそらくそのように書かれました。

_ 短めにキャストすると、パフォーマンスが低下しますか? _

上記の理由により:いいえ-とにかく発生する必要があります。


2


算術代入演算子を使用すると、キャストを実際に回避できることを付け加えました。 速くも遅くもありません。知っておくといいかもしれません。

short permissions = 0755;
short requested = 0700;
short result = permissions;
result &= requested;


2


実際、パフォーマンスが低下する可能性があります。 int`と long`の値に対するビット演算にはJavaバイトコードのみがあります。 したがって、「permission」変数と「requested」変数の「short」値は、操作が実行される前に(理論上)符号拡張される必要があります。

(さらに、ネイティブのビット単位の命令は32ビットと64ビットでのみ利用可能であることがわかると思います。 または、8または16ビットバージョンがある場合、32ビットバージョンと同じ数のクロックを使用します。 CPUデータパスは少なくとも32ビット幅であり、および/またはxorの場合、より狭い型をより速く動作させる方法はありません。)

さらに、3つの変数のタイプが「short」であっても、JVMはそれらを格納するために同じバイト数を割り当てます。 これは、JVMの設計方法の結果です。

したがって、「short」を使用する目的がスペースまたは時間を節約することである場合、おそらく役に立ちません。 しかし、確認する唯一の方法は、プロファイラーを使用して、アプリケーションの short`バージョンと int`バージョンを比較することです…​ またはそれ以上、それを忘れてください。


1


`&`演算子のオペランドはintに昇格されるため、結果はintになり、 `result`に格納する場合はshortにキャストする必要があります。 コンパイラがコードの生成に不得意でない限り、パフォーマンスが低下するとは思わない。

_ 演算子の両方のオペランド&、^、または|原始整数型に変換可能な型(§5.1.8)である場合、オペランドで最初にバイナリ数値プロモーションが実行されます(§5.6.2)。 _

_ […​] Otherwise, both operands are converted to type int. _