プロが教えるわが家の防犯対策術!

c言語の質問です。
ランダムに4桁の暗証番号を出力するプログラムを作ったのですが、4947→4973→4990→5006と数が増えていくだけでランダムになりませんでした。
一体どうしてでしょうか
コードは写真のとおりです。

「c言語の質問です。 ランダムに4桁の暗証」の質問画像

A 回答 (3件)

○たまたまです。


○ただ、そのrand()関数はそうなる傾向が強いです。



rand()関数で使われている乱数は、正確には「疑似乱数」といって、ただの計算結果です。

「種」を使って「最初の状態」を設定する

「最初の状態」を元に計算して、「乱数」と「次の状態」を求める

「次の状態」を元に計算して、「次の乱数」と「その次の状態」を求める

「そろ次の状態」を元に計算して、「そろ次の乱数」と「さらにその次の状態」を求める
...

とすると、「乱数」がバラバラの値に見えるような計算をしています。

計算しているだけなので、種が同じなら、同じ「乱数」が出てきます。
そこで、実行のたびに種が変わるようにするテクニックの一つが「種に現在時刻をつかう」というものです。 srand(time(NULL)) は、種にtime(NULL)で求めた「現在時刻を秒で表現した値」を使用しています。

種1と種2が違えば、乱数列1と乱数列2がまったく関係無い値になるのが理想です。
が、現実はそうもいきません。
そのrand関数の「計算」では
・種1と種2が近いと、乱数列1と乱数列2も近くなる傾向がある
・特に、下の桁ほどその傾向が強くなる。
という特徴があります。

このプログラムを連続で実行すると
現在時刻が近い
→種が近い
→乱数が近い
→%で下の桁を抜き出しているので、特に傾向が出やすい
となります。


対策としては
・種をtimeそのままではなく、工夫する
・rand() 1回で終了ではなく、複数実行する
・%1000ではなく、 (int)((rand() / ((double) RAND_MAX + 1.0)) * 10000) 等と全体を使うようにする
・rand()以外のアルゴリズムを使用する
等があります

https://ja.wikipedia.org/wiki/Rand
    • good
    • 1
この回答へのお礼

はえー!
そういうことだったんですね!
おもしろかったです。
原因だけでなく対策案も!
ありがとうございます!

お礼日時:2022/04/16 20:49

rand 関数ではなく


srand関数を使ってみたら?
    • good
    • 0

十分、ランダムになってますよ。


もっと、繰り返すと、数が減ることもあります。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!