2009/08/12

[memo] thread safe and portable random function?

スレッドセーフで移植性が高いrandom関数って書けないかしらん。と少し悩んで以下のように書いた。
#include <math.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
//
// returns random number from zero to max.
// to compile this, run the following command.
// $ gcc -Wall -lm -lrt filename
//
double getRand(struct drand48_data *data, int max)
{
double rand = 0;
drand48_r(data, &rand);
rand = floor(rand * max);
return rand;
}
int initRand(struct drand48_data *data)
{
struct timespec time;
int result = clock_gettime(CLOCK_REALTIME, &time);
if (result == -1) {
perror("clock_gettime");
return -1;
}
srand48_r(time.tv_nsec, data);
return 0;
}
int main(int argc, char *argv[])
{
int c, result;
struct drand48_data data;
result = initRand(&data);
if (result == -1) {
return result;
}
for (c = 0; c < 100; c++) {
printf("%.0f\n", getRand(&data, 500));
}
return 0;
}


型の問題を差し引いたとしても、残念なことに上記は移植性がない。関数 [d|s]rand48_r が GNU による拡張だからである。うまい方法を御存知の方がいらっしゃったら教えてくださいませ(´ー`; )

[ Update August 13th 0:03 JST by m ]

pascal君から指摘があったので全面的に書き直しました。古いバージョンは一度だけ呼ぶべき srand48_r関数 を毎回呼んでいました。指摘さんくすです。

2 件のコメント:

Unknown さんのコメント...

どもども。

全然質問と関係ないんだけど、
srand48_r(time.tv_nsec, &data);
は、乱数生成毎ではなくて、初期化時に1回だけ呼ぶべきだと思うです。

mumumu さんのコメント...

尤もな指摘ですね(´ー`; )
書き直しました。さんくすです。