私は次のことをしようとしています:
の位置から始まるビットをの右端のビットに設定し、他のビットは変更せず
setbits(x,p.n,y)
に返す関数を作成しますか?x
n
p
n
y
このように試してみましたが、正しい答えが得られませんでした。誰が私が間違っているか教えてもらえますか?
unsigned setbits(unsigned x,int p,int n,unsigned y)
{
return (x>>p & (y|(~0<<n)));
}
何かのようなもの:
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);
}
カーニハンとリッチー、第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))
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;
それでおしまい!実際にはテストしませんでしたが、うまくいけば、アイデアが得られるでしょう。
x>>()
は右端x
のビットを失い、後で機能するときにそれらを復元することはありません。 &
結果は両方のオペランドに依存するため、どちらか一方のみが構成されていることがわかっていない限り、のみを使用してビットを設定することはできません。1
(y|(~0<<n))
からビットを切り取ることになっていますy
が、そうではありません。今回|
は適切なツールではありません&
。適切な第 2 オペランドを使用してください。これが解決策です(もっと短いものがあるに違いありませんが、これは簡単です):
(x & ~(~(~0<<n)<<p) | (y&~(~0<<n)) << p);
の左側の部分は(位置 p の n ビット)|
の場所をクリアし、右側の部分はビットをもたらします。x
y