1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(int argc, char** argv) {


    srand(time(NULL));
    int r = rand();

    printf("%d\n", r);

    return (EXIT_SUCCESS);
}

このコード スニペットを数秒間隔で繰り返し実行すると、213252683、213975384、214193875、214445980 などの一連の数値が増加します。システム時間を出力しているように見えます-その仮説は行を追加するときに確認し printf("%d\n", time(NULL))ます。コードに。私は何を間違っていますか?Mac OS X 10.6.1 (Snow Leopard) で実行していますが、標準ライブラリ関数しか使用していないため、違いはありません。ありがとう!

4

5 に答える 5

3

疑似乱数は、初期シードから派生したカオス シーケンスとして生成されます。srandこのシードを設定してランダム性を初期化します。どうやら、シーケンスの最初の乱数はシード自体であり、time()設定した値です。

これが、ランダム シーケンスを生成する正しい方法がsrand()、プログラムの開始時に 1 回だけ呼び出すrand()ことである理由です。母関数に依存します)。あまりにも頻繁に呼び出すsrand()と、ご覧のとおり、ランダム性が低下します。

于 2012-05-06T00:48:30.103 に答える
1

それが役立つ場合、私は一般的にそのように使用します:

int rand_between(int min, int max)
{
  static int flag = 1;
  FILE *urandom;
  unsigned int seed;

  if (flag)
    {
      flag = 0;
      if (!(urandom = fopen ("/dev/urandom", "r")))
      fprintf(stderr, "Cannot open /dev/urandom!\n");
      fread(&seed, sizeof(seed), 1, urandom);
      srand(seed);
    }
  return ((int)rand() % (max - min)) + min;
}

ランダムな大文字を取得するには:

char letter = (char)rand_between('A', 'Z');
于 2012-05-06T04:51:19.373 に答える
0

rand()の代わりにrandom()を使用する必要があります。あらゆる点でrand()よりも優れており、stdlibにも含まれています。
次のコードを試してください。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
int r = random();
printf("%d\n", r);
return (EXIT_SUCCESS);
}
于 2013-01-22T04:06:51.603 に答える
0

乱数発生器は大きく異なるため、他のマシンで再現するのは困難です。実装の最初の数値は単なるシード値のようです。たとえば、私の場合、最初の数字はシードに直線的に関連しているように見えます。通常、srandプログラム内で1rand回、何度も呼び出すと、連続して呼び出すと、よりランダムに見える結果が得られます。この問題を回避したい場合は、次のことを行うのが合理的です。

srand(time(NULL));
rand();
int r = rand();

printf("%d\n", r);

最初のrand呼び出しはシードが返されないことを確認し、次の呼び出しはよりランダムに見えるものをピックアップする必要があります。十分に短い時間でプログラムを2回実行すると(time(NULL)両方の実行で同じになるように)、まったく同じ結果が得られることに注意してください。これは間違いなく予想されることです。これが問題になる場合は、別のシード値を使用してください(pid + time良いスタートか、より高い解像度の時間である可能性があります)。

于 2012-05-06T01:59:51.163 に答える
0

このコード スニペットを数秒間隔で繰り返し実行すると、213252683、213975384、214193875、214445980 などの一連の数値が増加します。

これを再現できません。私のシステム (Debian Linux) では、順序付けされていない番号が表示されます。また、結果は、印刷したときに得られるものと同じではありませんtime(NULL)

これはあるべき姿です: 乱数ジェネレーターに現在の時刻 (秒単位) をシードしています。したがって、時間 (秒まで) が同じである限り、プログラムは同じ結果を出力します。

私は何を間違っていますか?

まあ、それはあなたが望むものに依存します。実行ごとに乱数が必要な場合は、より良いランダム性のソースが必要です。のような高解像度の関数を試すことができますgettimeofday(通常は ms だと思います)。また、プロセスのIDなど、ランダム性の他のソースを混ぜてください。

ほとんどのプログラムでは、通常srand()は開始時にのみ呼び出され、rand()呼び出しごとに異なる番号が返されるため、表示される効果は問題ありません。

「安全な」(つまり、予測不可能な) 乱数が必要な場合、それはまったく別のゲームです。概要については、たとえばウィキペディアを参照してください。

于 2012-05-06T00:53:19.130 に答える