2

0から40(両端を含む)の乱数を生成しようとしています。だから私が実装したコードはこれです-

 y=rand()%41;

ただし、[コンパイル]をクリックして[実行]をクリックするたびに。同じ乱数を出力します。たとえば、私はこれをループで実行しました。

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

毎回、出力は同じ4つの数値です。常に端末に14.2などを出力します。何があっても。

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

次に、Cで乱数ジェネレーターはどのように機能しますか?

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

4

6 に答える 6

2

rand()疑似乱数のみを生成します。これは、コードを実行するたびに、まったく同じ数列が得られることを意味します。

使用を検討してください

srand(time(NULL))

毎回異なる番号を取得します。実際、可能な実装rand

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

ここで、nextは次のように定義されます

static UINT32 next = 1;

呼び出しsrand()には、の初期値を変更する効果がありnext、結果として取得する「次の」値を変更します。

于 2012-04-07T13:37:19.987 に答える
2

それがどのように機能するかについては、それは異なります。多くの実装では、パラメーターが異なる線形合同法ジェネレーターを使用します。

于 2012-04-07T13:44:35.927 に答える
2

に使用されるアルゴリズムrandは、C標準では指定されていません。

仕様により、プログラムでを呼び出すsrand前に呼び出さない場合は、呼び出されたかのようになります。シード値はプログラムの実行ごとになり、生成されるシーケンスは常に同じになります。randsrand(1)1

プログラムの実行ごとに異なるシードを使用する一般的な方法は、次のように現在の時刻に依存するシードを使用することです。

srand(time(NULL));  
于 2012-04-07T14:03:25.417 に答える
2

これは実際にはcomp.lang.cに関するFAQです。彼らが提案する解決策は次のとおりです。

(int)((double)rand() / ((double) RAND_MAX + 1) * N )

N乱数の範囲の上限はどこにありますか。これは、不良Cコンパイラの下位ビットが「驚くほどランダムではない」ためです。これでは、srand()を使用する必要はありません。ただし、srand(time(NULL))はループの外側で呼び出す必要があることに注意してください... time()の解像度は1秒なので、ループの内側で呼び出すと、乱数ジェネレーターが同じシードに再初期化されます。何度も続けて。

これの必要性はおそらく歴史的なものです。最近のコンパイラには、本当に悪い乱数を生成する乱数ジェネレータがないはずですが、BorlandCコンパイラを使用してプログラムを作成したことを覚えています。rand() % 41繰り返し使用しました。

于 2012-04-07T14:46:08.187 に答える
1

これは、シードを渡した引数によって生成されます。rand()異なる番号を生成するには、関数を呼び出す前にこれを追加します。

srand (time(NULL));

これにより、新しいランダムシードが生成されます。

このライブラリが必要#include <time.h>です。それでもエラーが発生する場合は、これも使用してください。#include <stdlib.h>

于 2012-04-07T13:36:22.353 に答える
1

理由は、rand()が実行するたびに同じシードを使用しているためです。自分でシードする必要があります。srand(time(NULL)); `は通常、ランダムシードを初期化するために使用されます。

于 2012-04-07T13:39:26.037 に答える