5

私は次のことをしようとしています:

の位置から始まるビットをの右端のビットに設定し、他のビットは変更せずsetbits(x,p.n,y)に返す関数を作成しますか?xnpny

このように試してみましたが、正しい答えが得られませんでした。誰が私が間違っているか教えてもらえますか?

unsigned setbits(unsigned x,int p,int n,unsigned y)
{
    return (x>>p & (y|(~0<<n)));
}
4

4 に答える 4

3

何かのようなもの:

unsigned setbits(unsigned x,int p,int n,unsigned y)
{
    unsigned mask = (1U << n) - 1U; // n-bits
    y &= mask; // rightmost n bits of y
    y <<= p;   // which begin at position p
    mask <<= p; //idem
    x &= ~mask; //set the 0s
    x |= y;     //set the 1s
    return x;
}

または、より少ない行で実行したい場合は、デバッグが難しくなりますが、もっとクールです:

unsigned setbits(unsigned x,int p,int n,unsigned y)
{
    unsigned mask = (1U << n) - 1U; // n-bits
    return (x & ~(mask << p)) | ((y & mask) << p);
}
于 2012-07-21T08:38:59.280 に答える
1

カーニハンとリッチー、第2版、演習2-6。解決策はhttp://users.powernet.co.uk/eton/kandr2/krx206.htmlからです:

(x & ((~0 << (p + 1)) | (~(~0 << (p + 1 - n))))) | ((y & ~(~0 << n)) << (p + 1 - n))

于 2012-07-21T08:32:48.033 に答える
1

y の最後の n ビットをキャッチ: (最後の n ビットが y に等しく、その他がゼロに設定された数値になります)

last_n_bits_of_y = y & (((1<<(n+1))-1);

次に、(32-n-p+1) でオフセットできます (これを確認してください!)

last_n_bits_of_y_offset = last_n_bits_of_y << (32-n-p+1);

次に、変更したい x のビットを消去します。

new_x = x & (~( (((1<<(n+1))-1) << (32-n-p+1) ) );

そして、ビットを入力します。

new_x = new_x & last_n_bits_of_y_offset;

それでおしまい!実際にはテストしませんでしたが、うまくいけば、アイデアが得られるでしょう。

于 2012-07-21T08:43:19.917 に答える
1
  1. あなたx>>()は右端xのビットを失い、後で機能するときにそれらを復元することはありません。
  2. &結果は両方のオペランドに依存するため、どちらか一方のみが構成されていることがわかっていない限り、のみを使用してビットを設定することはできません。1
  3. (y|(~0<<n))からビットを切り取ることになっていますyが、そうではありません。今回|は適切なツールではありません&。適切な第 2 オペランドを使用してください。

これが解決策です(もっと短いものがあるに違いありませんが、これは簡単です):

(x & ~(~(~0<<n)<<p) | (y&~(~0<<n)) << p);

の左側の部分は(位置 p の n ビット)|の場所をクリアし、右側の部分はビットをもたらします。xy

于 2012-07-21T08:48:24.493 に答える