-2

I'm trying to convert realy big numbers (>100 digits) from string to integer in Zn additive group (modulo n). n is guaranteed to be in standard C int range (say n=12345).

Neither the simple approach of atoi then "%", nor BigIntiger works here.

Any ideas how to implement that?

Dave
  • 463
  • 1
  • 3
  • 14
  • 3
    The tried and tested algorithm of converting the digits one by one, coupled with the fact the `(a + b) mod n = ((a mod n) + (b mod n)) mod n`, and the same for multiplication. – StoryTeller - Unslander Monica Dec 15 '15 at 13:07
  • Your only remaining problem is that you are going to want to write `answer = ((answer * 10)%n + digit)%10;` and that multiply can overflow if n is > MAXINT/10. (Even if you do it by repeated addition `(answer+answer)%n` can overflow if n is > MAXINT/2). – Martin Bonner supports Monica Dec 15 '15 at 13:09
  • @MartinBonner, that's a good reason to use types with explicit size from `` – StoryTeller - Unslander Monica Dec 15 '15 at 13:11
  • 4
    Do you want to do this in C or C++? They're not the same language and may have different solutions. Please pick one. – Samidamaru Dec 15 '15 at 13:20
  • It doesn't hurt, but it is not necessary to use `` (C++) or `stdint.h` (C) types. All of the standard integral types (`char`, `short`, `int`, `long`, `unsigned`, `long long`, etc) have a minimum range guarantee - although implementations are permitted to support a greater range than the standard required. If you know the upper limit on `n`, pick a type guaranteed able to represent at least twice that value. If `n` is too large for standard types, look up a "big integer" library type or something similar. – Peter Dec 15 '15 at 13:22
  • If you selected a data type big enough to hold 10n+9 it is pretty easy `answer=(answer*10+digit)%n` repeated for all digits left to right. That isn't much more than a data type big enough for `n` which you obviously need. – JSF Dec 15 '15 at 13:38
  • I'm sure there's a way to do it without a full blown bignum library. But I'm not sure waht. – Martin Bonner supports Monica Dec 15 '15 at 13:54

1 Answers1

3

I'm going to assume you meant C++ in your question (there is no such thing as C/C++). atoi converts a string into a number that can fit into a standard integer (32-bits), so that's not what you want. You'll have to write your own conversion function.

To keep the maths simple, let's assume that your number is positive. First note that addition and multiplication under modulus is equivalent to that without the modulus. So we only need to retain the result of those two operations, modulus n. Then note that we can construct the big number digit by digit:

unsigned int convert(const char* s, int n) {
    long long x = 0;
    for (char *p = s; *p; p++) {
        x *= 10;
        x += (int)(*p - '0');
        x %= n;
    }
    return x;
}

I left out any error checking for clarity. As an exercise, write some additional code to ensure that s is a valid null-terminated string representing a big integer without any whitespace/additional formatting.

austere
  • 157
  • 7