次のことが理解できません。
ジャバでは、
long l = 130L;
byte b = (byte)l;
b の値を出力すると、なぜ -126 になるのですか? long l のビット表現は何ですか?
1 バイトは 8 ビットのシーケンスで、2^8 ケース = 256 になります。それらの半分は負の数を表し、-128 から -1 です。次に 0 があり、約半分の 1 から 127 は正の数を表します。
Int としての 130 は 128 + 2 のように見えます。
0000:0000 1000:0000 (128)
0000:0000 0000:0010 (2)
0000:0000 1000:0010 (130)
ただし、Byte には 8 桁しかなく、割り当てはビットをそのまま使用しますが、最後のビットのみを使用します。
1000:0010
最初のビットは、負の数であることを示します。では、ゼロになるにはどれだけ追加する必要がありますか? 段階的にやってみましょう:
1000:0010 x +
0000:0001 1 =
----------------
1000:0011 (x+1)
1000:0011 (x+1) +
0000:0001 1 =
----------------
1000:0100 (x+2)
もっと大きな一歩を踏み出しましょう。ゼロがあるところに 1 を追加するだけですが、まず x に戻ります。
1000:0010 x +
0111:1101 y =
--------------
1111:1111
ここで転換点があります。さらに 1 を追加し、ゼロを取得します (プラス オーバーフロー)。
1111:1111 (x + y) +
0000:0001 1
---------
0000:0000 0
(x+y) + 1 = 0 の場合、x+y = -1。興味深いことに、マイナス 1 は、「負のフラグ」が設定された 1 (0000:0001) (「1000:0001」) と同じだけでなく、まったく異なって見えます。ただし、最初の位置は常に符号を示します。1 は常に負を示します。
しかし、前に何を追加しましたか?
0111:1101 y = ?
最初の位置に 1 がないので、正の値です。それを分解する方法を知っていますか?
..f:8421 Position of value (1, 2, 4, 8, 16=f, 32, 64 in opposite direction)
0111:1101 y = ?
..f 84 1 = 1+4+8+16+32+64= 125
そして今、それは明らかです: x+125 = -1 => x = -126
0 が上 (正午) に配置され、正の値が時計のように 0 から 5 (ただし 127) まで、下 (127 + 1 => -128 [sic!].) これで、時計回りに進み、1 リードを -127、-126、-125、... -3、-2、-1 (11 時の位置) に追加し、最後に再びトップに0。
より大きな数値 (small、int、long) の場合は、より大きなクロックを使用します。ゼロは常に上に、最大値と最小値は常に下になります。しかし、1 バイトでも画像を作成するには大きすぎるので、ニブルの 1 つ、半バイトを作成しました。
写真の穴を簡単に埋めることができます。
ところで、すべてはキャスティングとは呼ばれません。キャストはオブジェクト間でのみ使用されます。実際にはサブタイプである何かがある場合:
Object o = new String ("casting or not?");
String は (常に) Object であるため、これは単なる割り当てです。キャストは含まれません。
String s = (String) o;
これはキャストです。より具体的なタイプに。すべてのオブジェクトが String であるとは限りません。すべてのバイトをロスレスで long に変換できますが、すべての long をバイトに変換できるわけではないため、整数の昇格には小さな関係があります。ただし、Object 型である Byte と Long でさえ、相互に継承されません。
警告が表示されないだけです。
byte s = (byte) 42;
long o = s; // no problem, no warning
byte b = (byte) o; // written like casting
バイトは Java で署名されているため、値の範囲は -128 から 127 までです。
long としての 130 のビット パターンを単純に 8 ビットに切り詰めると、バイトとしての -126 のビット パターンになります。
別の例として:
int x = 255;
byte b = (byte) x; // b is now -1
つまりbyte b = (byte)l
?
Java の型は符号付きであるため、バイトは -128 から +127 までの数値を使用できます。