C++サンプル集

【第1部】C言語(K&R検証)編

0012.擬似乱数の発生

ソース紹介

CPPファイルに記述
#include <iostream>
#include <cstdio>
#include <ctime>
using namespace std;

unsigned long next_num = 1;

/*
0から32767の間の範囲の擬似乱数を発生させる
*/
int Rand() {
    next_num = next_num * 1103515245 + 12345;
    return (unsigned int)(next_num / 65526) % 32768;
}
/*
rand の種を設定
*/
void Srand(unsigned int seed) {
    next_num = seed;
}

/*
乱数のテスト
*/
int main()
{
    //乱数のseedを初期化
    Srand((unsigned int)time(nullptr));
    int arr[100];
    //配列の初期化
    for (int i = 0; i < 100; i++) {
        arr[i] = 0;
    }
    //乱数を発生させ、カウンタをインクリメント
    for (int i = 0; i < 1000000; i++) {
        arr[Rand() % 100]++;
    }
    //結果出力。各数値が何個づつ発生したか確認
    for (int i = 0; i < 100; i++) {
        cout << i << '\t' << arr[i] << endl;
    }
    return 0;
}
出力
0       9947
1       10081
2       10152
3       10086
4       10198
5       9905
6       10081
7       9848
8       9955
9       9907
10      10040
11      9957
12      9995
13      10143
14      10065
15      10079
16      9953
17      9916
18      9877
19      10120
20      10077
21      9994
22      10080
23      10076
24      9864
25      9900
26      10157
27      10005
28      10054
29      10037
30      10009
31      9892
32      10010
33      10014
34      10044
35      10099
36      10037
37      10089
38      10000
39      10123
40      10067
41      10158
42      10096
43      10003
44      9967
45      9972
46      10097
47      10034
48      10008
49      10090
50      10019
51      10009
52      10120
53      10041
54      9936
55      9923
56      9982
57      9914
58      9847
59      9990
60      9972
61      10147
62      9998
63      10088
64      9960
65      9932
66      9937
67      10031
68      9819
69      9995
70      9998
71      9900
72      9842
73      9932
74      9997
75      9982
76      9978
77      9842
78      9958
79      9849
80      9890
81      10203
82      9811
83      9982
84      9934
85      10022
86      9873
87      10198
88      9968
89      10054
90      9911
91      10132
92      9959
93      9952
94      9901
95      9976
96      9942
97      9973
98      9969
99      10054

サンプル説明

 このテストは1000000回(百万回)乱数を発生させ、それぞれを100で割ったあまりが、どのように分布されているかを確認しています。
 こうしてみると、分布的には、ほどほどばらけていると思います。ただ、どのような順番で出きているかはテストしてないので、それは各自やってみるとよいと思います。
 ここで紹介されている擬似乱数発生アルゴリズム線形合同法を使ってます。
    next_num = next_num * 1103515245 + 12345;
 のように固定値をもとに計算しています(初期化に使用するSEEDはtime()でとってきますが)。
 擬似乱数の計算方法はいろんな人が、ブログなど書いているので、調べてみると面白いでしょう。

K&Rでの記述

 元になったのは第2章:データ型・演算子・式に記述されています。型変換の説明のところです。