-3

We are given two integers a and b, a <= 100000, b < 10^250. I want to calculate b%a. I found this algorithm but can't figure out how it works.

int mod(int a, char b[])
{
    int r = 0;
    int i;
    for(i=0;b[i];++i)
    {
      r=10*r +(b[i] - 48);
      r = r % a;
    }
    return r;
}

Please explain the logic behind this. I know basic properties of modular mathematics.

Thanks.

daft300punk
  • 169
  • 3
  • 16
  • The only magic number here is 48. It is ASCII code of symbol "0". So `"0" - 48 == 0;` and `"1" - 48 == 1;` and so on. The rest of the code is up to you to understand. – Teivaz Apr 07 '15 at 10:44
  • 1
    @MarkGraph your sarcasm is better than your guess. – daft300punk Apr 07 '15 at 10:51
  • 3
    The piece of code you "found" does not take "two integers, a and b", so this is not a very good start. – Daniel Daranas Apr 07 '15 at 10:53
  • @teivaz i knew what 48 did. That was not magic at all. i was looking for was how that algorithm got the answer for b%a. – daft300punk Apr 07 '15 at 10:53
  • 1
    @DanielDaranas i wrote that we are given two integers. I did not say anything about how I input it. In this case, as is obvious the bigger number b is input as string. – daft300punk Apr 07 '15 at 10:55
  • Integer will **always** be smaller than 10^250 – Thomas Ayoub Apr 07 '15 at 11:14
  • 1
    He didn't deserve the downvotes. He forgot to explain how the value iof `b` is entered and supposed you downvoters will understand it. This is the only thing he got wrong about. His question about how this function computes the modulo **is** interesting and easily linked to the way one effciently compute a polynomial. [Horner's Algorithm](http://en.wikipedia.org/wiki/Horner's_method) – fjardon Apr 07 '15 at 11:25

2 Answers2

3

It's pretty easy to figure out if you know modular arithmetics, expression (b[n] + 10 * b[n - 1] + ... + 10^k * b[k] + ... + 10^n * b[0]) modulo a which is technically initial problem statement could be simplified to (...((b[0] modulo a) * 10 + b[1]) modulo a) * 10 + ... + b[n]) modulo a which is what your algorithm does.

To prove that their equal we may calculate coefficient modulo a before b[i] in the second expression, it's easy to see that for b[i] there will be exactly n - i times we'll have to multiply it by 10 (the last one which is n will be multiplied 0 times, the one before him 1 time and so on ...). So modulo a it equals 10 ^ (n - i) which is the same coefficient before b[i] in the first expression.

Thus since all coefficients before b[i] in both expressions would be equal, it's obvious that both expressions are equal to (k_0 * b[0] + k_1 * b[1] ... + k_n * b[n]) modulo a and thus they are equal modulo a.

48 is char code for 0 digit, so (b[i] - 48) is conversion from char to digit.

Predelnik
  • 5,066
  • 2
  • 24
  • 36
  • I don't get how it has been simplified to (...((b[0] modulo a) * 10 + b[1]) modulo a) * 10 + ... + b[n]) modulo a – daft300punk Apr 07 '15 at 11:00
  • @AbhilashSingh to calculate coefficient before `b[i]` you will have to multiple `10 modulo a` from exactly `n - i` parenthesis which is the same as `(10^(n - i)) modulo a` from the first expression. – Predelnik Apr 07 '15 at 11:02
1

Basically this function implements Horner's Algorithm to compute the decimal value of b.

As @Predelnik explained, the value of b is a polynomial whose coefficients are the digits of b and the variable x is 10. The function computes the modulo on every iteration using the fact that modulo is compatible with addition and multiplication:

(a+b) % c = ((a%c) + (b%c)) % c
(a*b) % c = ((a%c) * (b%c)) % c
fjardon
  • 7,921
  • 22
  • 31