Modulo of Multiplication of Big Numbers in C

Recently I had some difficulties to generate pseudo-random numbers in C by using Lehmer’s method. Lehmer random number generator is an easy-to-implement algorithm that provides random number stream. Basically you have a multiplier (a) and modulus (m) which you use in a basic arithmetic to get next number. Let we have the initial seed $$s$$, than the following numbers can be obtained as

$$ s = ( sa ) \pmod{m} $$

and if you want to get uniform numbers between zero and one, then you can divide $$s$$ to $$m$$. The major problem is, when $$m$$ is a big number (like $$2^{31} -1$$) then you may get some very big numbers for $$s$$. Later when I need to multiply big numbers, like $$s=65467721$$, multiplying this number with my multiplier $$a=48271$$ was leading to overflow. Let’s try the following code:

C

1

2

3

4

ints1=65467721;

printf("s1: %d\n",s1);

s1=((s1)*48271L)%2147483647;

printf("s1: %d\n",s1);

The output is

1

2

s1:65467721

s1:-903569465

As you see our multiplication leaded overflow thus returned a negative number, which has no value. A quick fix to this problem is adding “unsigned long long” in front of $$s$$. Consider the following code:

C

1

2

3

4

ints2=65467721;

printf("s2: %d\n",s2);

s2=((unsignedlonglong)(s2)*48271L)%2147483647;

printf("s2: %d\n",s2);

which gives

1

2

s2:65467721

s2:1243915654

It was actually a bug in the latest project I’m coding. After driving me nuts for 2 weeks, I finally get rid of the problem once and for all.