Cでのビットの右回転
私はK&Rの演習2-8に取り組んでいます。この演習rightrot(int x, int n)
でx
は、のすべてのビットが右にn回シフトされ、右端から落ちたビットが左端に再び表示されるように関数を作成するように求められます。
これは、各ビットを1つずつシフトするという私の試みた解決策です。
int rightrot(int x, int n)
{
int i, rmb;
for(i = 0; i < n; ++i)
{
// get right-most bit
rmb = x & 1;
// shift 1 to right
x = x >> 1;
// if right-most bit is set, set left-most bit
if (rmb == 1)
x = x | (~0 ^ (~0 >> 1) );
}
return x;
}
私は実行するとrightrot(122, 2)
、私が得ることを期待94
以来122
である1111010
と94
されます1011110
。代わりに、30
たまたまどちらかがわかります0011110
。明らかに、左端のビットを設定する私の方法は、期待どおりに機能していません。誰かが明らかなエラーを見つけましたか?ビットのキャプチャなどについて学んでいます。
注:この投稿から、左端のビットを設定するためのテクニックを入手しました。
回答
7 mch
分析しましょう(~0 ^ (~0 >> 1) )
:
~0
は-1
~0 >> 1
再び-1
です。符号ビットが1
右シフトの場合、新しいビットは1
sで埋められます。
-1 ^ -1
です0
。
x = x | 0
ですx
。
解決策は、ビット操作を実行する場合は、符号なしデータ型を使用する必要があるということです。
したがって、この行x = x | (~0u ^ (~0u >> 1) );
を使用するx
必要がありますunsigned int
。他の問題を回避するには、パラメーターも。
https://ideone.com/7zPTQk