5

I am learning Pascal on my own for a month now and I came up to one problem I can't seem to solve. Basically I have 2 numbers, N and M, where N is less than 10100 000 and M is less than 108 and both are greater than 0. I need to calculate N mod M.

I can't figure out how to do it, not even with QWord. I tried it with string but I don't know a good way. It always ends up too complex for me because I use a for function where I get the last number from the string N and string M then I subtract them with two if functions (where last digit of N is higher or the same as last digit of M, and if it's lower). Basically it gets too complex for this easy problem I think.

Luka
  • 187
  • 3
  • 9
  • Also with string i have to do a lot of transfering from string to integer, then integer to string or char etc... – Luka Feb 17 '14 at 20:23
  • Can you post your code so far? – John Kugelman Feb 17 '14 at 20:27
  • You'd need **over 3 million** bits to store a number of the magnitude of 10^100000 (which is a [googol](http://en.wikipedia.org/wiki/Googol), incidentally). As a comparison, the information capacity of the observable universe is about 10^305 bits [reference here](http://en.wikipedia.org/wiki/Orders_of_magnitude_%28data%29). In short, there's no way to do this easily. Why do you need such large numbers? –  Feb 17 '14 at 20:28
  • 2
    "... and N is less than 10^8"? Do you mean "... and M is less than 10^8"? – Johan Råde Feb 17 '14 at 20:29
  • 3
    @MikeW What do you mean there's no way to do this easily? I don't see how the information capacity of the universe is relevant to doing bignum calculations. – John Kugelman Feb 17 '14 at 20:30
  • @JohnKugelman If you have an easy way to this I'd be pleased to see it. –  Feb 17 '14 at 20:38
  • How are you storing the numbers? Are you storing them in some kind of scientific notation, or are we talking about a string of numbers that is actually 10^100,000 digits long? If it's the former, then it should be doable. If it's the latter then I don't think it's possible with current technology. – milestyle Feb 17 '14 at 20:47
  • @MikeW I have no idea if this calculation is possible or not, but I do know that your reasoning is specious. Physics is not relevant here. This is a mathematical question. If you have a number theoretical or computer scientific argument why this calculation is difficult, please share. – John Kugelman Feb 17 '14 at 20:48
  • @milestyle Note that the string of digits would be 100,000 digits long, not 10^100,000 digits. – John Kugelman Feb 17 '14 at 20:49
  • 1
    This is a problem from one of the older competitions in Pascal in my country, and they haven't posted solutions. It really intrigues me how to solve it, and btw i know about googol, googolplex, googolplexian etc. but i think this doesn't any connections to physics :) And yes, the number would be 10^100 000 which is 1 followed by 100 000 zeroes. And guess what, time limit for this problem is 0.1 second – Luka Feb 17 '14 at 20:55
  • @JohnKugelman You have 'no idea if this calculation is possible': it is. Implementing arbitrary precision arithmetic in binary or BCD is possible to any size. It's not, however, straightforward. If you're going to make accusations of 'specious' reasoning, I'd like to see your own reasoning. –  Feb 17 '14 at 20:57
  • @MikeW My reasoning about what? [Let's take this to chat.](http://chat.stackoverflow.com/rooms/47698/how-to-calculate-with-a-number-this-big) – John Kugelman Feb 17 '14 at 20:58
  • I can't talk in the chat room, i need 20 reputation :\ – Luka Feb 17 '14 at 21:04
  • I have 21 rep and it still says i need 20 reputation to talk :( – Luka Feb 17 '14 at 21:13
  • 1
    [How do you calculate the modulo of a high-raised number?](http://math.stackexchange.com/q/195634/100055) – Rob Kennedy Feb 19 '14 at 15:29

1 Answers1

3

There are some bignum packages floating around, e.g. the the open source MPArith package from http://www.wolfgang-ehrhardt.de/mp_intro.html. With the included demo calculator you can easily beat your time limit:

D:\Xtools\MPArith>t_calc.exe
T_CALC using MPArith V1.26.05 (31/32 bit) [mp_calc]  (c) W.Ehrhardt 2006-2013
Karatsuba cutoffs:  mul/sqr = 16/32,   Toom-3 cutoffs: mul/sqr = 32/64
Burnikel/Ziegler div cutoff = 32,   MaxBit = 520093696,   MaxFact = 22623931
Type "?<enter>" to get some info about commands, "\q" or "quit" to end.

[D]:=> 10^100000 mod (10^8-1)
Result = 1
[D]:=> .
Time = 20.128 ms
[D]:=> 10^100000;
Result =  [>0, 332193 bits,  chksum=$CE01C341,  time=46.994 ms]

But depending on your requirements and examples you may even get your results without bignum packages. If you want to compute a ^ b mod n you do not compute a ^ b and then reduce mod n in a second step, but you reduce every product in a loop. And you should use fast binary exponentiation, see e.g. the description and pseudo code at http://en.wikipedia.org/wiki/Modular_exponentiation. For modules n of order 10^8 you need to reduce a product of two 31/32 bit integers and therefore you need int64 or so to accumulate the products (which should not be a problem for you Pascal version which has QWord). I guess such a program would be much faster than the MPArith bignum code with it's 20 milliseconds.

gammatester
  • 1,131
  • 1
  • 8
  • 12