2.2 rand(), srand()

UNIX マシンならば、 man 3 rand でオンライン・マニュアル読んでみよう。 関数 rand()$0$ から RAND_MAX (これは stdlib.h に定義されている) までの整数値を取る、 周期 $2^{32}$ の数列の各項を順番に 返す1

乱数の種 (seed) を変更するには、 srand(seed); を実行すれ ば良い。

/*
 * test-rand.c
 */

/*
 * rand() は
 *  BSD では 0 から 2^{31}-1 までの範囲の疑似乱数を返す。
 *  SYSTEM V では 0 から 2^{15}-1 までの範囲の疑似乱数を返す。
 *
 */

#include <stdio.h>
#include <stdlib.h> /* rand(),srand() */

int main()
{
  int i, n;
  n = 10;
  printf("start\n");
  for (i = 0; i < n; i++)
    printf("%d\n", rand());
  /* seed を 3 にしてやり直し */
  srand(3);
  printf("start (seed=3)\n");
  for (i = 0; i < n; i++)
    printf("%d\n", rand());
  /* seed を 1 にしてやり直し (最初と同じになる) */
  srand(1);
  printf("start (seed=1)\n");
  for (i = 0; i < n; i++)
    printf("%d\n", rand());

  return 0;
}

ゲームのプログラミングなどでは、システムの時刻を読み取って、 乱数の種となるデータを生成することがよく行なわれる。 シミュレーションをする場合にもそれをしてよいだろうが、 追試が出来るように種を記録しておくべきであろう。

/*
 * test-rand2.c
 */

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

#include <sys/types.h>
#include <sys/time.h>

int main()
{
  int i, n, myseed; 
  time_t tloc;

  n = 10;
  time(&tloc);
  myseed = tloc;
  srand(myseed);
  printf("start (seed=%d)\n", myseed);
  for (i = 0; i < n; i++)
    printf("%d\n", rand());

  return 0;
}

種を time() で安直に設定するには、 (tloc, myseed などを省略して)
  srand((unsigned)time(NULL));
くらいで良いかも。

$[0, 1]$ に正規化したい場合は RAND_MAX で割算 すればよいだろう2

/*
 * test-rand3.c
 */

/*
 * rand() は 0 から RAND_MAX までの範囲の疑似乱数を返す。
 *  ゆえに割算すれば [0,1] の範囲の疑似乱数値を返す。
 */

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

double drand()
{
  return rand() / (double) RAND_MAX;
}

int main()
{
  int i, n;
  n = 10;
  printf("start\n");
  for (i = 0; i < n; i++)
    printf("%f\n", drand());
  return 0;
}

桂田 祐史
2017-04-29