短いGetBits(短いデータ、int型のp、int型のn):関数を書きます
質問
私は、関数の短いgetBits(短いデータ、int型のp、int型n)を書いています。
私が試してみました。
public static short getBits(short data, int p, int n) {
short bitmask = (short) ((~0 << (16 -n)) >>> p);
short returnVal = (short) ((bitmask & data) >>> (16 - n));
return returnVal;
}
これはgetBits((ショート)0x7000、0、4)の作品が、私は8と7を交換した場合、私は負の値を取得します。
解決
この事を動作させるために、Javaのデータ型について覚えておくべきいくつかの事があります。
私は、あなたはあなたのために式の明示的なキャストの有無のint型の変数を使用していると仮定しています。あなたは、変数の型にint使用している場合:データstart_pos、および長さを、 int型の32ビット値なので、あなたは、32の代わりに16を使用する必要があります。
また、あなたは、これらのプリミティブ型は、あなたが〜0のような負の数の右シフトを行う場合(つまり、符号拡張されている2の補数であることを覚えて、int型、ショートやバイトなどの整数のプリミティブ型を使用するつもりなら、ものではなく、ゼロの)上位ビット(符号ビットに付加されます。)-1と評価
たとえばます:
1111 1111 1111 1111 1111 1111 1111 1000
>>1
1111 1111 1111 1111 1111 1111 1111 1100
さて、あなたの問題に戻ります。一般的な考え方は行うことができるようにすることです。
data & mask
次に、マスクを生成すると、署名されたデータ型のビットトリッキーです。これは、使用してマスクを生成するために理にかなってます:
(~0 << (32 - length) >> (32 - length - start_pos))
しかし、これは、符号拡張のはもちろん動作しません。
私はその代わりに右シフトを使用することをお勧め>>、代わりに使用するものは、上位ビットに追加されるのでそのよう>>>演算子を回転させ、回転演算子は下位ビットを付加します。
たとえばます:
1111 1111 1111 1111 1111 1111 1111 1000
>>>1
0111 1111 1111 1111 1111 1111 1111 1100
そう...
mask = (~0 << 32-length >>> 32-length-start_pos)
そして、次のようになりますあなたの最終的な答えます:
(data & (~0 << 32-length >>> 32-length-start_pos)) >>> start_pos
最も外側の回転動作は下位ビットにあなたのマスクされたデータを移動します。
他のヒント
あなたが短い使用する必要がなぜわかりません。ここでは、長い使用したソリューションです。
public static long getBits(long data, int p, int n) {
assert p >= 0 && p < 64;
assert n >= 0 && n < 64;
return (data >> p) & ((1 << n) - 1);
}