2012-11-20 9 views
7

WindowsにGMPをインストールするという悪夢は望んでいません。符号なしlong long AとBに対してオーバーフローのない(A * B)mod Mを行う方法はありますか?

私は2つの数字AとB、unsigned long longを10^10程度の大きさで持っていますが、((A%M)*(B%M))%Mを実行しても整数オーバーフローが発生します。

数字が大きい場合は(A*B)%Mを計算するための自作関数がありますか?

+1

Mの大きさの順序はどのくらいですか? – jxh

+0

同じ、約10^10 –

+1

基本的にM * Mはオーバーフロー? –

答えて

9

モジュラスMULLONG_MAX(これが10^10の領域にある場合)よりも十分に小さい場合は、2つの要素の1つを分割することで3段階で行うことができます。私はそれがA < MB < MM < 2^42と仮定します。

// split A into to parts 
unsigned long long a1 = (A >> 21), a2 = A & ((1ull << 21) - 1); 
unsigned long long temp = (a1 * B) % M; // doesn't overflow under the assumptions 
temp = (temp << 21) % M;     // this neither 
temp += (a2*B) % M;      // nor this 
return temp % M; 

は、より大きな値については、次の3つの部分に係数を分割することができますが、弾性率はULLONG_MAXに本当に近くなった場合、それは醜いとなります。

+0

甘いgoogly mooglies、私はこれが動作すると信じています。ありがとうございました –

関連する問題