5

For example, A=10^17, B=10^17, C=10^18.
The product A*B exceeds the limit of long long int.
Also, writing ((A%C)*(B%C))%C doesn't help.

bolov
  • 72,283
  • 15
  • 145
  • 224
user3158621
  • 53
  • 1
  • 4
  • 3
    [This question](http://math.stackexchange.com/q/99018/21713) on MathOverflow seems related – aland Jan 03 '14 at 20:26
  • You can apply math to find shortcuts, though this won't necessarily get you down to numbers that fit into `long long int` (in this case, I think it doesn't simply because the result can be as large as 10^18). In that case, you need arbitrary precition integers. The obvious, non-optimal algorithm should be enough for numbers like 10^18, which is only a few dozen digits regardless of base. –  Jan 03 '14 at 20:31

2 Answers2

2

You can use

or

If you work only with power of 10 numbers, you could create a simple class with 2 members: a base and the power of 10, so A=10^17 would be {1, 17}. Implementing adding, subtracting, multiply and division is very easy and so is the print.

bolov
  • 72,283
  • 15
  • 145
  • 224
2

Assuming you want to stay within 64-bit integer operations, you can use binary long division, which boils down to a bunch of adds and multiply by two operations. This means you also need overflow-proof versions of those operators, but those are relatively simple.

Here is some Java code that assumes A and B are already positive and less than M. If not, it's easy to make them so beforehand.

// 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;
}
xan
  • 7,511
  • 2
  • 32
  • 45
  • The C++ code is almost identical, changing `long` to `long long` and `Long.MAX_VALUE` to `std::numeric_limits::max()` – xan Sep 28 '17 at 23:00