5

Suppose I have a integer array containing digits and I want to take modulus of value stored in it, i.e

 int a[36]={1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9} 

and convert it into a number like 987654321987654321987654321987654321.

In C language long long int permits only 10^18. I want to take modulus with 10^9+7. How can i do that?

Program:

int main()
{
int a[36]={1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9};
long long int temp=0;
int i;
for(i=0;i<36;i++)
{
     temp=temp+a[i]*pow(10,i);
}
temp=temp%1000000007;
printf("%lld",temp);
return 0;
}
Vasu Dev Garg
  • 121
  • 1
  • 15

1 Answers1

3

Since 36 decimal digits is too much for a typical long long, you need to perform your modulus operation during the conversion:

int a[36]={1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9};
long long int temp=0;
for(int i=35 ; i >= 0 ; i--) {
    temp = 10*temp + a[i];
    temp %= 1000000007;
}
printf("%lld",temp);

I made two changes to your code:

  • Fixed the way you convert an array of digits to a number - your code used pow, and treated digits at higher indexes as higher-order digits. This creates precision problems once you get past the highest power of ten that can be represented as double.
  • Moved the %= into the loop - your code does not let the number overflow by keeping the value in the range from 0 to 1000000006, inclusive.

Running this code produces the same value that you would obtain with a library that supports arbitrary precision of integers (I used Java BigInteger here).

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 1
    the idiom `for (int i=35 ; i >= 0 ; i--) { ... }` is error prone: the correct type for `i` should be `size_t` and the initial value should be `sizeof a / sizeof *a` or at worst the same magic constant as used for the length of `a`. I would suggest: `for (size_t i=36 ; i-- > 0 ; ) { ... }` – chqrlie May 28 '15 at 17:35
  • @chqrlie Moving side effects into the condition for the loop does the trick, but its readability suffers tremendously, especially to an untrained reader. I would let OP beautify his own code to his own liking: the important point is to do the `%=`s inside the loop, and to not use `pow` which loses precision when `i` gets too high. – Sergey Kalinichenko May 28 '15 at 17:43
  • I fully agree regarding the main computation issue. As for the downward loop, both approaches are equally inelegant, an alternative is to move the decrement to the body eg: `temp = 10*temp + a[--i];`, but that's looks even worse. – chqrlie May 28 '15 at 19:48