私は「JavaのTCP/IPソケット、第2版」という本を読んでいます。もっとわかりやすくしたかったのですが、本のウェブサイトにはフォーラムなどがないので、ここで聞いてみようと思いました。いくつかの場所で、本は符号拡張を避けるためにバイトマスクを使用しています。次に例を示します。
private final static int BYTEMASK = 0xFF; //8 bits
public static long decodeIntBigEndian(byte[] val, int offset, int size) {
long rtn = 0;
for(int i = 0; i < size; i++) {
rtn = (rtn << Byte.SIZE) | ((long) val[offset + i] & BYTEMASK);
}
return rtn;
}
だから、これが何が起こっているのかについての私の推測です。私が正しいかどうか教えてください。
BYTEMASK
バイナリではのようになります00000000 00000000 00000000 11111111
。簡単にするために、val
バイト配列にはshortが1つしかないため、オフセットは0であるとしましょう。バイト配列をval[0] = 11111111
、に設定しましょうval[1] = 00001111
。でi = 0
、rtn
はすべて0なのでrtn << Byte.SIZE
、値を同じに保ちます。次に(long)val[0]
、符号拡張のためにすべて1で8バイトになります。ただし、を使用する& BYTEMASK
と、余分な1はすべて0に設定され、最後のバイトはすべて1のままになります。次に、rtn | val[0]
基本的にの最後のバイトの任意の1を反転するものを取得しますrtn
。の場合i = 1
、(rtn << Byte.SIZE)
最下位バイトをプッシュし、すべての0をそのままにします。次に(long)val[1]
、すべてゼロのプラスで長くなります00001111
必要な最下位バイトの場合。したがって、使用& BYTEMASK
しても変更されません。次に、が使用されると、最下位バイトがすべて1rtn | val[1]
に反転します。rtn
最終的な戻り値はになりrtn = 00000000 00000000 00000000 00000000 00000000 00000000 11111111 11111111
ました。ですから、これが長すぎず、理解できたと思います。私はこれについて私が考えている方法が正しいかどうかを知りたいだけであり、論理を完全に狂わせただけではありません。また、私を混乱させる1つのことBYTEMASK
はです0xFF
。バイナリでは、これはになります11111111 11111111
。したがって、暗黙的にintにキャストされている場合、実際には11111111 11111111 11111111 11111111
符号拡張が原因ではないでしょうか。その場合、どのように機能するかは私には意味がありませんBYTEMASK
。読んでくれてありがとう。