C#で循環ビットシフトを実行する方法はありますか?
-
09-06-2019 - |
質問
私は次のことが真実であることを知っています
int i = 17; //binary 10001
int j = i << 1; //decimal 34, binary 100010
ただし、シフトしすぎるとビットが端から落ちてしまいます。これがどこで起こるかは、扱う整数のサイズによって決まります。
ビットが反対側に回転するようにシフトを実行する方法はありますか?for ループではなく、単一の操作を探しています。
解決
型のサイズがわかっている場合は、次のようなことができます。
uint i = 17;
uint j = i << 1 | i >> 31;
...これは 32 ビット値の循環シフトを実行します。
b ビット変数に対して n ビット左循環シフトを一般化すると、次のようになります。
/*some unsigned numeric type*/ input = 17;
var result = input << n | input >> (b - n);
@コメントでは、C#は符号付き値の上位ビットを異なる方法で処理しているようです。これに関する情報を見つけました ここ. 。また、uint を使用するように例を変更しました。
他のヒント
1 年前、学部の論文で MD4 を実装する必要がありました。これは、UInt32 を使用した循環ビット シフトの実装です。
private UInt32 RotateLeft(UInt32 x, Byte n)
{
return UInt32((x << n) | (x >> (32 - n)));
}
やり方の参考として、この 2 つの関数は 1/2word のビットを回転させるのに完璧に機能します。
static public uint ShiftRight(uint z_value, int z_shift)
{
return ((z_value >> z_shift) | (z_value << (16 - z_shift))) & 0x0000FFFF;
}
static public uint ShiftLeft(uint z_value, int z_shift)
{
return ((z_value << z_shift) | (z_value >> (16 - z_shift))) & 0x0000FFFF;
}
任意のサイズに拡張するのは簡単です。
正直に言うと、「C# ビット回転」を検索して見つけたところです。 C# に簡単に適応できる Java クラスを含むページへのリンク
最も有名な応用例は、ヨセフス問題の解法です (具体的な数学で説明されているように、を参照してください)。 http://oeis.org/A006257)。これは基本的にパズルであり、明確な応用はありません。で このビデオ, 二次ヨセフス問題と完全平衡ツリーとの関連性を実証しました。まだ応用ではありませんが、少しずつ正しい方向に進んでいます。
所属していません StackOverflow