質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

5467閲覧

C言語で乱数が毎回同じ値になってしまう

Courange

総合スコア17

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2019/11/07 11:46

前提・実現したいこと

C言語で12つの選択肢から一つをランダムに選ぼうとするコードを書いても毎回同じになってしまう。

発生している問題・エラーメッセージ

該当のソースコード

c

1 2#include<stdlib.h> 3#include<stdio.h> 4#include<time.h> 5 6int GetRandom(int min,int max); 7int main(){ 8 9 int ran,min=0,max=11; 10 ran = GetRandom(min,max); 11 12 /*結果発表*/ 13 printf("<%d>が選ばれました\n",ran); 14 system("pause"); 15 16 return 0; 17} 18 19/*乱数取得用*/ 20int GetRandom(int min,int max) 21{ 22 static int flag; 23 24 if (flag == 0) { 25 srand((unsigned int)time(NULL)); 26 flag = 1; 27 } 28 29 return min + (int)(rand()*(max-min+1.0)/(1.0+RAND_MAX)); 30} 31

output

1<0>が選ばれました

試したこと

time()関数を使ってrand関数の初期値?(引数の値?)を指定しているはずなのですが、毎回同じ数値が出力されます。

以下のサイトを参考にしております
苦しんで覚えるC言語

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ozwk

2019/11/07 12:57 編集

コピペして動かしてみましたがちゃんと違う値になりました(ideone) 環境を追記してください
guest

回答3

0

ベストアンサー

C

1int GetRandom(int min,int max) 2{ 3 static int flag; 4 5 if (flag == 0) { 6 srand((unsigned int)time(NULL)); 7 flag = 1; 8 } 9 int r = rand(); 10 printf("rand() = %d factor = %lf\n", r, (max-min+1.0)/(1.0+RAND_MAX)); 11 return min + (int)(r*(max-min+1.0)/(1.0+RAND_MAX)); 12}

rand() と factor:(max-min+1.0)/(1.0+RAND_MAX) をプリントしてみると
factorがかなり小さい(0に近い)のが原因であるように思われます。

標準ライブラリの乱数(srand()/rand())は決して質の良いものではないので(特にVisual C++のは)、
シミュレーションなどが目的でより良い乱数がご所望でしたらメルセンヌ・ツイスタあたりを使うが吉ではないかと。

投稿2019/11/07 12:24

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Courange

2019/11/07 14:26

ご回答ありがとうございます。 丁寧で分かりやすかったですm(_ _)m
episteme

2019/11/07 22:01

逆にさほどの質を求めないなら rand()%12 で十分に思えます。
guest

0

次のコードを実行してみてください。

C

1#include <stdio.h> // printf 2#include <stdlib.h> // srand, rand 3#include <time.h> // time 4 5int main() 6{ 7 srand(time(0)); 8 for (int i = 0; i < 10; i++) 9 printf(" %d", rand()); 10}

VC++ の場合、1秒以上の間をあけて何度も実行しても、
1番目の乱数は似たような値になります。
time() の返す値が似ているからでしょう。
srand() の後に rand() を 1回カラ打ちして、
2番目以降の値を使うとよいのではないでしょうか?

投稿2019/11/07 12:16

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Courange

2019/11/07 14:24

なるほど やってみます
Courange

2019/11/07 14:25

int GetRandom(int min,int max) { static int flag; if (flag == 0) { srand((unsigned int)time(NULL)); flag = 1; } for(int i = 0;i < 1 + (int)( rand() * (10) / (1.0 + RAND_MAX) );i++){ } return min + (int)( rand() * (max - min + 1.0) / (1.0 + RAND_MAX) ); }
Courange

2019/11/07 14:26

これで無事解決できました。 本当にありがとうございました。
kazuma-s

2019/11/07 14:35 編集

for文が必要ですか? sand((unsigned int)time(NULL)); のすぐあとに rand(); と書くだけで 1回目の乱数を捨てられます。
guest

0

乱数の品質というかsrandの性質が悪いのではないでしょうか。
長時間おいて実行してみるとか、
srand((unsigned int)time(NULL)*(unsigned int)time(NULL)*(unsigned int)time(NULL));
とかにしてみるとか。

投稿2019/11/07 12:06

otn

総合スコア84555

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問