2012-04-07 13 views
2

0から40までの乱数を生成しようとしています。 だから私は実装されたコードは、私がコンパイルクリックして実行]をヒットthis-乱数ジェネレータはどのようにCで動作しますか?

y=rand()%41; 

しかし毎回です。同じ乱数を出力します。 たとえば、私はこれをループで実行しました。

for(i=0;i<4;i++) 
{ 
    y=rand()%41; 
    printf("%d ",y); 
} 

毎回、出力は同じ4つの数字です。端末には常に14,2などが出力されます。どんなものでも。

私の最初の質問は、なぜこれが起こっているのですか?

第2に、乱数ジェネレータはどのようにCで動作しますか?

私はtime.hライブラリを含めるので、数字はシステム時間を使っていくつかの標準的なアルゴリズムによって生成されると思った。システム時間が絶えず変化しているので、プログラムを実行するたびに生成される数値も変わるはずです。

+1

もし 'x 'が' RAND_MAX'を分割しない 'rand()%x'を使うと、その分布は一様ではありません。 – harold

+0

しかし、それはここでのポイントではありません。 –

+1

@ H2CO3だからこそ、これはコメントであり、答えではありません。 – harold

答えて

2

rand()は、擬似乱数を生成します。つまり、コードを実行するたびに、まったく同じ数字列が得られます。

はたびに異なる番号を取得するために

srand(time(NULL)) 

を使用することを検討してください。実際にrandのための可能な実装はnext

static UINT32 next = 1; 

srand()を呼び出すように定義されて

next = next * 1103515245 + 12345; 
return (UINT32)(next>>16) & RAND_MAX; 

あるので、あなたに取得する「次」の値を変更し、nextの初期値を変更する効果を持っています結果。

+2

実際には 'rand'アルゴリズムが指定されていません – ouah

+0

@ouahはい、私は答えを編集しました – Saphrosit

+0

別の番号を取得するたびにrngを再シードするべきではないことを明確にします。あなたはRAND_MAX要求番号に近づくにつれて、それを最初に一度だけ植えるべきです。また、多くのrngがウォームアップ期間を必要とすることに気付く価値があります。これは通常state_size * 4です。残念ながら、randの実装を知る方法はないので、あなたはその状態の大きさを知らないでしょう。多くの実装はリニアジェネレータであり、状態はありません。 – Rabbit

1

引数が渡されたシードによって生成されます。

srand (time(NULL)); 

これは新しいランダムシードを生成します:異なる番号を生成するには、rand()関数を呼び出す前にこれを追加します。

あなたはこのライブラリを持っている必要があります:#include <time.h>そして、あなたはまだ、同様のエラー使用にこれを持っている場合:#include <stdlib.h>

+0

私はrand関数を呼び出すたびにそれを追加しますか? –

+0

はい、私はそう思います。とにかく試してみてください。 –

+0

あなたはそうする必要はありません。各シードは一連の疑似乱数の原因となります。 – chris

1

理由は、実行するたびにrand()が同じシーディングを使用しているということです。あなたはそれを自分で播種しなければなりません。 srand(time(NULL)); `は通常、ランダムシードの初期化に使用されます。

2

どのように動作するかは、依存します。多くの実装では、異なるパラメータを使用してLinear Congruential Generatorを使用します。あなたのプログラムでrandへの呼び出しの前にsrandを呼び出さない場合srand(1)が呼び出されたかのように

2

randのために使用されるアルゴリズムは、C規格で規定されていない、仕様によって

は、それがある:シード値プログラムの実行ごとに1となり、生成されるシーケンスは常に同じになります。これは、実際にcomp.lang.c.のFAQです

srand(time(NULL)); 
2

プログラムの実行するごとに異なる種を持っている一般的な方法は、現在の時間等に依存種子を使用することですここでは、彼らが提案するソリューションです:

Nは乱数のあなたの範囲の上限である
(int)((double)rand()/((double) RAND_MAX + 1) * N) 

。これは、悪いCコンパイラの下位ビットが「衝撃的に非ランダム」であるためです。これは、srand()を使用する必要性を回避しません。しかし、srand(time(NULL))はの外側にあると呼ばれるべきです。time()は1秒の分解能を持っていますので、ループの中で呼び出すと乱数ジェネレータが同じ種が何度も連続しています。

これはおそらく歴史的なものですが、現代のコンパイラにはおそらく乱数発生器がない乱数生成器はないと思いますが、Borland Cコンパイラを使ってプログラムを書くことを覚えています。私がrand() % 41を繰り返し使用したときに約5つの数字。

関連する問題