整数クラスに符号なし左回転を実装したいと考えています。ただし、これはテンプレート クラスであるため、128 ビットから任意のサイズにすることができます。そのため、同じサイズの一時を必要とするアルゴリズムを使用することはできません。型が大きくなると、スタック オーバーフローが発生するためです (特に、そのような関数が呼び出しチェーンにある場合)。
したがって、このような問題を解決するために、質問を最小限に抑えました。4ビットのみを使用して32ビットの数値を回転させるには、どのような手順を実行する必要がありますか. 考えてみれば、32 ビットの数値にはそれぞれ 4 ビットのグループが 8 つ含まれているため、ローテーションするビット数が 4 の場合、グループ0 and 4
、1 and 5
、2 and 6
、の間でスワップが発生3 and 7
し、その後ローテーションが行われます。
ローテーションするビットが 4 未満で 0 より大きい場合は、単純に最後のN
ビットを保存して shift-Or ループを開始します。たとえば、0x9CE2
左に 3 ビットローテーションする数値があるとします。
リトル エンディアン バイナリの数値は で1001 1100 1110 0010
、各ニブルは右から左に 0 から 3 のインデックスが付けられ、この数値N
と 1 つのグループのビット数を呼びます。B
[1] x <- N[3] >> 3
x <- 1001 >> 3
x <- 0100
y <- N[0] >> (B - 3)
y <- N[0] >> (4 - 3)
y <- 0010 >> 1
y <- 0001
N[0] <- (N[0] << 3) | x
N[0] <- (0010 << 3) | 0100
N[0] <- 0000 | 0100
N[0] <- 0100
[2] x <- y
x <- 0001
y <- N[1] >> (B - 3)
y <- N[1] >> (4 - 3)
y <- 1110 >> 1
y <- 0111
N[1] <- (N[1] << 3) | x
N[1] <- (1110 << 3) | 0001
N[1] <- 0000 | 0001
N[1] <- 0001
[3] x <- y
x <- 0111
y <- N[2] >> (B - 3)
y <- N[2] >> (4 - 3)
y <- 1100 >> 1
y <- 0110
N[2] <- (N[2] << 3) | x
N[2] <- (1100 << 3) | 0111
N[2] <- 0000 | 0111
N[2] <- 0111
[4] x <- y
x <- 0110
y <- N[3] >> (B - 3)
y <- N[3] >> (4 - 3)
y <- 1001 >> 1
y <- 0100
N[3] <- (N[3] << 3) | x
N[3] <- (1001 << 3) | 0110
N[3] <- 1000 | 0110
N[3] <- 1110
結果は1110 0111 0001 0100
、0xE714
16 進数で です。これが正しい答えです。そして、任意の精度で任意の数値に適用しようとする場合、必要なのは、その bignum 型を形成する配列の任意の要素の型である 1 つの変数だけです。
実際の問題は、ローテーションするビット数が 1 つのグループよりも大きいか、型の半分のサイズよりも大きい場合 (つまり、この例では 4 ビットまたは 8 ビットよりも大きい場合) です。
通常、最後の要素から最初の要素にビットをシフトします。ただし、最後の要素を最初の要素にシフトした後、回転するビット数が要素 (つまり> 4 bits
) よりも大きいため、結果を新しい場所に再配置する必要があります。シフトが開始される開始インデックスは最後のインデックス (この例では 3) であり、宛先インデックスには次の式を使用dest_index = int(bits_count/half_bits) + 1
しhalf_bits
ます。最初のシフトの結果は宛先インデックス 2 に再配置する必要があります。これが私の問題です。この状況のアルゴリズムを作成する方法が思いつかないからです。half_bits = 8
bits_count = 7
dest_index = int(7/8) + 1 = 1 + 1 = 2
ありがとう。