4

私は「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 = 0rtnはすべて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。読んでくれてありがとう。

4

1 に答える 1

6

最後の点を除いてすべてが正しいです:

0xFFはすでにint0x000000FF)であるため、符号拡張されません。一般に、Javaの整数リテラルは、 orで終わり、その後がintsでない限り、sです。Lllong

于 2012-05-06T19:07:35.783 に答える