1

関数 short getBits(short data, 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( (short) 0x7000, 0, 4) で機能しますが、7 を 8 に置き換えると負の値になります。

4

2 に答える 2

2

これを機能させるために、Javaデータ型について覚えておくべきことがいくつかあります。

式に明示的なキャストがないため、int変数を使用していると想定しています。変数にint型を使用している場合:data start_pos、およびlength; intは32ビット値であるため、16ではなく32を使用する必要があります。

また、int、short、byteなどの整数プリミティブ型を使用する場合は、これらのプリミティブ型は符号拡張された2の補数であることに注意してください。つまり、〜0などの負の数を右シフトすると(-と評価されます) 1)、0の代わりに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

最も外側の回転操作は、マスクされたデータを下位ビットに移動します。

于 2009-06-30T05:15:19.533 に答える
1

なぜ short を使用する必要があるのか​​ わかりません。これが long を使用したソリューションです。

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);
}
于 2009-11-01T16:11:39.160 に答える