乱数を得る


指定範囲の乱数の取得

ゲームや、機械の判断にゆだねられるような処理をする場合
可変で予想できない、適当な値乱数を得る必要があります

乱数の取得には stdlib.h ヘッダファイルを利用します
このヘッダファイルにはrand()関数が用意されています

int rand( void );

この関数は、呼び出されるたびに擬似乱数を返します
ここで得られる乱数は0からRAND_MAXの範囲内の数値です

RAND_MAXはstdlib.hに定義されている定数で
ANSI C標準のコンパイラでは少なくとも32768の値を持ちます
#include <stdio.h>
#include <stdlib.h>

int main() {
	int count;
	for (count = 0 ; count < 10 ; count++)
		printf("%d\n" , rand());

	return 0;
}
これを実行すると10行にわたって適当な値が出力されます
しかし、もう一度実行したところ同じ順序で値が出力されます
これは、rand()関数が計算で擬似乱数を発生されているためで、これでは乱数とは呼べません

そこで、擬似乱数を生成するための初期値を変更します
初期値を指定しなかった場合は 1 を初期値として擬似乱数を出しています

初期値の指定はsrand()関数が行います
この関数もstdlib.hヘッダファイルに定義されていて、
rand()関数を使う前に呼び出して初期値を指定します

void srand( unsigned int seed );

seedに乱数を生成するための値を指定します
ここの値を可変にすることで、乱数は適当な値になります
もちろん、一定の値であれば乱数は常にその値から生成されるので
やはり同じ結果しか返さない乱数になる

常に変化する値といえば、前回説明したシステム時刻が適任ではないでしょうか?
ということで、この場ではtime()関数を使って初期化します
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
        int count;
        srand((unsigned)time( NULL ));
        for (count = 0 ; count < 10 ; count++) {
                printf("%d\n" , rand());
        }

        return 0;
}
これでも、計算で結果を出している以上ある程度規則的ですが
乱数としての精度は十分です
時間は、プログラムを起動するたびに異なるので
結果として、常に異なる値で乱数を初期化することができています

さて、常に異なる適当な値を得ることはできました
しかし、この状態では特定の範囲内の乱数を得ることができませんね
通常は、30000近くまでの広い範囲の乱数を用いることはありません
逆に、30000以上の広い範囲の乱数を得たい時もありますね

これは、rand()関数で得られた結果を算術演算して解決します
指定範囲の乱数を得る場合は最大値で除算した余りで求めることができます
つまり、0〜9の乱数がほしい場合は、rand() % 10 とするのです
(乱数の精度にシビアなシステム設計では、この方法は推奨されません)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
        int count;
        srand((unsigned)time( NULL ));
        for (count = 0 ; count < 10 ; count++) {
                printf("%d\n" , rand() % 10);
        }

        return 0;
}
これで、0〜9までの乱数だけが返されます

最後に、rand()関数の乱数の精度を確認しましょう
0か1の乱数を算出させ、その結果を変数に格納して比較します
確立が2分の1であれば、お互いの数は近いはずですね
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
	int count , one = 0 , zero = 0;
	srand((unsigned)time( NULL ));
	for (count = 0 ; count < 100000 ; count++) {
		if (rand() % 2) one++;
		else zero++;
	}
	printf("0 = %d : 1 = %d" , zero , one);
	return 0;
}
おそらく、0と1の割合はほぼ2分の1に近いはずです
このプログラムでは10万回、乱数を発生させているので
変数zeroとoneは5万に近い値のはずです


int rand( void );

擬似乱数を発生させます

ヘッダ - stdlib.h

戻り値 - 0〜RAND_MAXの範囲内のint型擬似乱数

void srand( unsigned int seed );

乱数の初期値を指定します

ヘッダ - stdlib.h
seed - 乱数生成の初期値を指定します



前のページへ戻る次のページへ