4

A、B、Cの3つの大きな64ビット数があります。計算したいもの:

(A x B) mod C

私のレジスタが64ビットであることを考えると、つまり、書き込みa * bは実際には(A x B)mod2⁶⁴を生成します。

それを行うための最良の方法は何ですか?私はCでコーディングしていますが、この場合、言語は適切ではないと思います。


この解決策を指すコメントに賛成票を集めた後:

(a * b) % c == ((a % c) * (b % c)) % c

具体的に説明します。((a%c)*(b%c))はまだ2⁶⁴よりも大きい可能性があり、レジスタがオーバーフローして間違った答えが返されるため、これは解決策ではありません。してただろう:

(((A mod C)x(B mod C))mod2⁶⁴)mod C

4

1 に答える 1

8

コメントで指摘したように、カラツバのアルゴリズムが役立つかもしれません。しかし、まだ問題があり、別の解決策が必要です。

推定

A =(A1 << 32)+ A2

B =(B1 << 32)+B2。

それらを掛けると、次のようになります。

A * B =((A1 * B1)<< 64)+((A1 * B2 + A2 * B1)<< 32)+ A2*B2。

したがって、合計したい3つの数値があり、そのうちの1つは2 ^ 64よりも確実に大きく、もう1つは2^64よりも大きい可能性があります。

しかし、それは解決できました!

一度64ビットシフトする代わりに、それをより小さなシフトに分割し、シフトするたびにモジュロ演算を実行できます。結果は同じになります。

C自体が2^63より大きい場合でも問題になりますが、その場合でも解決できると思います。

于 2013-02-13T16:44:01.580 に答える