如何计算 A、B、C <= 10^18 的 (A*B)%C(以 C++为单位)?

How can I calculate (A*B)%C for A,B,C <= 10^18, in C++?

本文关键字:为单位 C++ lt 计算 何计算      更新时间:2023-10-16

例如,A=10^17, B=10^17, C=10^18.
产品 A*B 超过长长 int 的限制。
此外,写入 ((A%C)*(B%C))%C 也无济于事。

假设你想保持在 64 位整数运算内,你可以使用二进制长除法,它归结为一堆加法并乘以两个运算。这意味着您还需要这些运算符的防溢出版本,但这些版本相对简单。

下面是一些 Java 代码,它假设 A 和 B 已经是正数并且小于 M。如果没有,很容易事先制作它们。

// assumes a and b are already less than m
public static long addMod(long a, long b, long m) {
    if (a + b < 0)
        return (a - m) + b;  // avoid overflow
    else if (a + b >= m)
        return a + b - m;
    else
        return a + b;
}
// assumes a and b are already less than m
public static long multiplyMod(long a, long b, long m) {
    if (b == 0 || a <= Long.MAX_VALUE / b)
        return a * b % m;   // a*b > c if and only if a > c/b
    // a * b would overflow; binary long division:
    long result = 0;
    if (a > b) {
        long c = b;
        b = a;
        a = c;
    }
    while (a > 0) {
        if ((a & 1) != 0) {
            result = addMod(result, b, m);
        }
        a >>= 1;
        // compute b << 1 % m without overflow
        b -= m - b; // equivalent to b = 2 * b - m
        if (b < 0)
            b += m;
    }
    return result;
}
您可以使用

  • GNU 多精度算术库

    https://gmplib.org/

  • C++ 大整数库

    https://mattmccutchen.net/bigint/

如果您只使用 10 的幂,

则可以创建一个包含 2 个成员的简单类:一个基数和 10 的幂,因此 A=10^17 将是 {1, 17}。实现加、减、乘和除非常容易,打印也是如此。