This is developed from @Mark's answer using the BSD rand() function.
rand1() computes the nth random number, starting at seed, by stepping through n times.
rand2() computes the same using a shortcut. It can step up to 2^24-1 steps in one go. Internally it requires only 24 steps.
If the BSD random number generator is good enough for you then this will suffice:
#include <stdio.h> const unsigned int m = (1<<31)-1; unsigned int a[24] = { 1103515245, 1117952617, 1845919505, 1339940641, 1601471041, 187569281 , 1979738369, 387043841 , 1046979585, 1574914049, 1073647617, 285024257 , 1710899201, 1542750209, 2011758593, 1876033537, 1604583425, 1061683201, 2123366401, 2099249153, 2051014657, 1954545665, 1761607681, 1375731713 }; unsigned int b[24] = { 12345, 1406932606, 1449466924, 1293799192, 1695770928, 1680572000, 422948032, 910563712, 519516928, 530212352, 98880512, 646551552, 940781568, 472276992, 1749860352, 278495232, 556990464, 1113980928, 80478208, 160956416, 321912832, 643825664, 1287651328, 427819008 }; unsigned int rand1(unsigned int seed, unsigned int n) { int i; for (i = 0; i<n; ++i) { seed = (1103515245U*seed+12345U) & m; } return seed; } unsigned int rand2(unsigned int seed, unsigned int n) { int i; for (i = 0; i<24; ++i) { if (n & (1<<i)) { seed = (a[i]*seed+b[i]) & m; } } return seed; } int main() { printf("%u\n", rand1 (10101, 100000)); printf("%u\n", rand2 (10101, 100000)); }
It's not hard to adapt to any linear congruential generator. I computed the tables in a language with a proper integer type (Haskell), but I could have computed them another way in C using only a few lines more code.
srandseedsrand, andsrandomseedsrandom.