2013-12-13 13 views
5

私はEclipseで次のコードを書いた:整数型とlong型のJavaのビット演算子ですか?

byte b = 10; 
/* some other operations */ 
b = ~b; 

Eclipseは、ビット単位の補数のラインでバイトにキャストを望んでいました。それは言った: "タイプの不一致:intからバイトに変換することはできません"。私は他のビット演算と他の整数型でもこれを試しました。それは短いとcharと同じだった。 longおよびintegerのみがビット単位の操作を使用できます。

これには理由がありますか?

+1

おそらく、コンピュータは少なくとも32ビット長のレジスタ全体に対して演算を実行する必要があるからです。 – user2573153

+0

うん!それが理由かもしれません。 –

答えて

11

(例えば~など)単項および二項演算子のJava対象におけるそれぞれ"unary numeric promotion" (JLS, Section 5.6.1)"binary numeric promotion" (JLS, Section 5.6.2)にそのオペランド、「第一少なくともint観光を促進する」ための空想の用語。上方連結JLSセクションを引用単項数値昇格のための具体的

、:

いくつかの演算子は、数値型の値を生成しなければならない単一オペランドに単項数値昇格適用:

...オペランドがコンパイル時の型バイト、短い、またはcharである場合、それは拡大プリミティブ変換によってint型の値に昇格される(§ 5.1.2)。

(バイナリ数値昇格は、両方のオペランドを操作する、同様です。)

ので、bbyte場合でも、bの値が第一intに昇進したので~bは、intあります。

ソリューション:byteに戻ってそれをキャスト:

b = (byte) (~b); 

なぜ、Javaの?

それでは、その理由は何ですか?私が見つけることができる演算子、byte s、shorts、およびcharで動作するためのJVMバイトコード命令が存在しないようです。たとえば、使用している単項ビット補数演算子(〜)is implemented as an "XOR" operation with -1 (all bits set)。そのリンクから:

tempSpock &= ~mask; 

25 iload_2 // Push local variable 2 (mask). 
26 iconst_m1 // Push -1. 
27 ixor // Bitwise EXCLUSIVE-OR top two ints: ~mask 

しかし、私はできだけfind instructions for XOR(および他の単項および二項演算子のためにあまりにも)int sおよびlongのための(floatdoubleバージョンになり、他の事業者のために存在します適切な場において)。

したがって、byteshort、またはcharにこれらの操作を実行するためのバイトコード命令がないため、Javaはこれらのプロモーションを実行する必要があります。

なぜ、JVMですか?

これは別の質問をもたらします。なぜ、JVMはそのようなバイトコード命令をサポートしていませんか?答えは、「1バイトの命令セットですべてをエンコードするにはあまりにも多くのものがあるからです」と思われます。 JVM Specification, Section 2.11.1によると、

は、Java仮想マシンの 1バイトのオペコードサイズ、その命令セットの設計上のオペコードの場所の圧力へのエンコードの種類を考えます。各型付き命令がすべてのJava仮想マシンの実行時データ型をサポートする場合、 は、バイトで表現できる命令以上の命令があります。代わりに、Java仮想マシンの命令セットは、特定の操作に対してタイプサポートのレベルを低下させます。換言すれば、命令セットは意図的に直交していない。サポートされていないデータ型とサポートされているデータ型を必要に応じて変換するには、別の命令を使用できます。

(強調鉱山)

結論として、JVMの一バイトコード命令セットは、単項数値昇格し、二項数値昇格を必要と、バイトコードbyte S上のほとんどの操作のための指示、char S、およびshort Sを排除。

+0

あなたのバイトコード引数はナンセンスです。これが言語で指定されていれば、コンパイラはキャストを非常にうまく追加できます。例については、 'short ='に '+ ='がどのように定義されているかを見てください。 – starblue

3

はい、ほとんどの演算子のオペランドとして使用すると、intより小さい型は昇格になります。それらは最初にintに効果的にキャストされます。したがって、上記のコードでは、結果のタイプはintです。詳細については、JLSのthis sectionを参照してください。

については、 Javaがこれを実行する理由はわかりません。しかし、1つのもっともらしい理由は、Cがこれを行い、馴染みのあるセマンティクスを維持することが、おそらく言語設計の目的だったということです。

関連する問題