0

了解しました。長い整数で4つの整数をラップします。4つの整数にはすべて、最初の2バイトに配置された3つの値が含まれています。

 +--------+--------+
 |xxpppppp|hdcsrrrr|
 +--------+--------+

{pppppp}は1つの値を表し、{hdcs}は2番目の値を表し、{rrrr}は最後の値を表します。

長い間、これらの整数を4つパックしたいと思います。私は次のことを試しました:

ordinal = (c1.ordinal() << (14*3) | c2.ordinal() << (14*2) | c3.ordinal() << 14 | c4.ordinal());

ここで、c1.ordinal()... c4.ordinal()はラップする整数です。

テストを実行すると、これは機能しないようです。longの最後の整数の値を調べたいとしましょうc4.ordinal()。ここで、{pppppp} = 41、{hdcs} = 8、{rrrr} = 14の場合、次の結果が得られます。

System.out.println(c4.ordinal() & 0xf); //Prints 14
System.out.println(hand.ordinal() & 0xf); // Prints 14 - correct

System.out.println(c4.ordinal() >> 4 & 0xf); // Prints 8
System.out.println(hand.ordinal() >> 4 & 0xf); // Prints 8 - correct

System.out.println(c4.ordinal() >> 8 & 0x3f); // Prints 41
System.out.println(hand.ordinal() >> 8 & 0x3f); // Prints 61 - NOT correct!

さて、以下は私には奇妙です。次のように、最初の2つの整数を削除し、最後の2つだけをラップするとします。

ordinal = (c3.ordinal() << 14 | c4.ordinal());

同じテストを実行すると、正しい結果が得られます。

System.out.println(c4.ordinal() >> 8 & 0x3f); // Prints 41
System.out.println(hand.ordinal() >> 8 & 0x3f); // Prints 41 - correct!

何が悪いのかわかりません。そして、最初の2つの整数を削除すると、正しい答えが得られるということは、私には意味がありません。私はこれが長いデータ型に関係しているかもしれないと考え始めていますが、この理論をサポートするものはまだ見つかりません。

4

1 に答える 1

6

結果を に代入している場合でもlong、すべての操作はint値で実行されるため、上位ビットは失われます。long値を明示的に a に拡張することにより、 a への「昇格」を強制しますlong

long ordinal = (long) c1.ordinal() << (14*3) | 
               (long) c2.ordinal() << (14*2) | 
               (long) c3.ordinal() <<    14  | 
               (long) c4.ordinal();

また、各値の上位 2 ビットが 0 であることに確信がない限り、他の問題が発生する可能性があります。安全のためにこれらをマスクしたいかもしれません:

long ordinal = (c1.ordinal() & 0x3FFFL) << (14*3) | 
               (c2.ordinal() & 0x3FFFL) << (14*2) | 
               (c3.ordinal() & 0x3FFFL) <<    14  | 
               (c4.ordinal() & 0x3FFFL);
于 2010-02-25T15:00:09.883 に答える