byte、short、およびintが符号付きであるとすると、Javaのbyteおよびshortが通常の符号付き2の補数処理を受けないのはなぜですか?たとえば、0xffはバイトに対して無効です。
これは前にここで議論されましたが、私はこれが事実である理由を見つけることができませんでした。
符号付きバイトに格納するために使用される実際のメモリ-1
を見ると、それがであることがわかります0xff
。ただし、言語自体では、バイナリ表現で0xff
はなく、単に1バイトの範囲外です。のバイナリ表現-1
は実際に2の補数を使用しますが、その実装の詳細からは保護されます。
言語設計者は、-128から127までしか保持できないデータ型に255を格納しようとすると、エラーと見なされるべきであるというスタンスをとっただけです。
コメントで、Javaが許可する理由を尋ねます。
int i = 0xffffffff;
リテラル0xffffffff
はint
リテラルであり、2の補数を使用して解釈されます。バイトに対して同様のことを実行できない理由は、リテラルがタイプbyte
、または実際に。であることを指定するための構文が言語に提供されていないためshort
です。
より多くのリテラル型を提供しないという決定がなされた理由はわかりません。単純さの理由で作られたと思います。この言語の目標の1つは、不必要な複雑さを回避することでした。
You can write
int i = 0xFFFFFFFF;
but you can't write
byte b = 0xFF;
as the 0xFF is an int
value not a byte
so its equal to 255. There is no way to define a byte or short literal, so you have to cast it.
BTW You can do
byte b = 0;
b += 0xFF;
b ^= 0xFF;
even
byte b = 30;
b *= 1.75; // b = 52.
それは合法ですが、範囲外であるため、明示的にバイトにキャストする必要があります。つまり、(byte)0xffです。
You can literally set a byte, but surprisingly, you have to use more digits:
byte bad = 0xff; // doesn't work
byte b = 0xffffffff; // fine
The logic is, that 0xff is implicitly 0x000000ff, which exceeds the range of a byte. (255)
It's not the first idea you get, but it has some logic. The longer number is a smaller number (and smaller absolute value).
byte b = 0xffffffff; // -1
byte c = 0xffffff81; // -127
byte c = 0xffffff80; // -128
byte
-128〜127の範囲で可能な値。
範囲外の値を変数に割り当てて、オーバーフローを黙って破棄することは可能ですが、それは便利というよりはむしろ混乱を招きます。
次に、次のようになります。
byte b = 128;
if (b < 0) {
// yes, the value magically changed from 128 to -128...
}
ほとんどの場合、そのように「修正」するよりも、値が範囲外であることをコンパイラーに通知させる方が適切です。