Cでのビットの右回転

Jan 03 2021

私は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である111101094されます1011110。代わりに、30たまたまどちらかがわかります0011110。明らかに、左端のビットを設定する私の方法は、期待どおりに機能していません。誰かが明らかなエラーを見つけましたか?ビットのキャプチャなどについて学んでいます。

注:この投稿から、左端のビットを設定するためのテクニックを入手しました。

回答

7 mch Jan 02 2021 at 23:21

分析しましょう(~0 ^ (~0 >> 1) )

~0-1
~0 >> 1再び-1です。符号ビットが1右シフトの場合、新しいビットは1sで埋められます。
-1 ^ -1です0
x = x | 0ですx

解決策は、ビット操作を実行する場合は、符号なしデータ型を使用する必要があるということです。

したがって、この行x = x | (~0u ^ (~0u >> 1) );
を使用するx必要がありますunsigned int。他の問題を回避するには、パラメーターも。

https://ideone.com/7zPTQk