rand()これは、BSD関数を使用して @Mark の回答から開発されました。
rand1()seedn 回ステップスルーすることにより、 から始まる n 番目の乱数を計算します。
rand2()ショートカットを使用して同じことを計算します。一度に 2^24-1 ステップまでステップアップできます。内部的には 24 ステップしか必要ありません。
BSD乱数ジェネレーターで十分な場合は、これで十分です。
#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));
}
線形合同ジェネレーターに適応することは難しくありません。適切な整数型 (Haskell) を使用して言語でテーブルを計算しましたが、数行のコードを追加するだけで、C で別の方法でテーブルを計算することもできました。