除数大于两个大因子时的模积

时间:2019-12-19 19:15:46

标签: c++ multiplication modulo

在我的C ++代码中,我有三个uint64_t变量:

uint64_t a =  7940678747;
uint64_t b = 59182917008;
uint64_t c = 73624982323;

我需要找到(a * b) % c。如果我直接将ab相乘,将导致溢出。但是,我无法应用公式(a * b) % c = ((a % c) * (b % c)) % c,因为c > a, c > b以及因此的a % c = aa % c = b最终将a和{{ 1}},这将再次导致溢出。

如何为变量的这些值(通常是这种情况)计算b,而不会溢出?

3 个答案:

答案 0 :(得分:2)

一个简单的解决方案是定义x = 2^32 = 4.29... 10^9
然后将ab表示为:

a = ka * x + a1 with ka, a1 < x
b = kb * x + b1 with kb, b1 < x

然后

a*b = (ka * x + a1) * (kb * x + b1) = ((ka * kb) * x) * x 
      + x * (b1 * ka) + x * (a1 * kb) + a1 * b1

假设所有操作都在Z / cZ中执行,即假设% c操作在每个操作(*或+)之后执行,所有这些操作都可以不需要较大的类型来执行

答案 1 :(得分:1)

还有比这更优雅的解决方案,但是一个简单的解决方案就是寻找一个可以处理更大数量数据的图书馆。它会为您处理对于大多数普通类型而言太大的数字。签出此内容:https://gmplib.org/

答案 2 :(得分:1)

创建一个类或结构来处理部分数字。

PsuedoCode示例

// operation enum to know how to construct a large number
enum operation {
    case add;
    case sub;
    case mult;
    case divide;
}
class bigNumber {
    //the two parts of the number
    int partA;
    int partB;

    bigNumber(int numA, int numB, operation op) {
        if(op == operation.mult) {
            // place each digit of numA into an integer array
            // palce each digit of numB into an integer array
            // Iteratively place the first half of digits into the partA member
            // Iteratively place the second half of digits into the partB member
        } else if //cases for construction from other operations
    }

    // Create operator functions so you can perform arithmetic with this class
}

uint64_t a =  7940678747;
uint64_t b = 59182917008;
uint64_t c = 73624982323;  

bigNumber bigNum = bigNumber(a, b, .mult);
uint64_t result = bigNum % c;
print(result);

请记住,如果c的值非常小,则可能需要输入bigNumber类型的结果。基本上,这只是一个概述,请确保是否使用不会溢出的类型。