cc [ flag ... ] file ... -lsunmath -lm [ library ... ]
#include <sunmath.h>
int i_addran_(void);
float r_addran_(void);
double d_addran_(void);
void i_addrans_(int *x, int *n, int *l, int *u);
void u_addrans_(unsigned *x, int *n, unsigned *l, unsigned *u);
void r_addrans_(float *x, int *n, float *l, float *u);
void d_addrans_(double *x, int *n, double *l, double *u);
void i_get_addrans_(int *x);
void r_get_addrans_(float *x);
void d_get_addrans_(double *x);
void i_set_addrans_(int *x);
void r_set_addrans_(float *x);
void d_set_addrans_(double *x);
void i_init_addrans_(void);
void r_init_addrans_(void);
void d_init_addrans_(void);
これらの関数は、int、unsigned int、float、または double 型の均等に分布した乱数を生成します。各関数は、次の形式を繰り返し使用して、順番に次の乱数を生成します。
next = table[i] - table[(i - 24) % ADDRAN_SIZE]; table[i] = next; i = (i + 1) % ADDRAN_SIZE;
これらの関数の内部では、プログラムのスレッドごとに、ADDRAN_SIZE 要素の 3 つの別々のテーブルが保持されます。ADDRAN_SIZE は、<sunmath.h> に定義されています。
i_addran_() は、32 ビット整数の乱数を返します。連続数は、32 ビットの整数算術演算 (つまり、2**32 を法とする) で計算されるため、-2147483648 から 2147483647 までの範囲となります。
r_addran_() は、0 から 1 - 2**-24 までの範囲で単精度浮動小数点の乱数を返します。必要に応じて 1 を加算すると、この範囲内で連続数が保持されます。
d_addran_() は、0 から 1 - 2**-53 までの範囲で倍精度浮動小数点の乱数を返します。必要に応じて 1 を加算すると、この範囲内で連続数が保持されます。
i_addrans_(n, x, l, u)、u_addrans_(n, x, l, u)、r_addrans_(n, x, l, u)、および d_addrans_(n, x, l, u) は、配列要素 x[0], ..., x[*n-1] に、それぞれ 32 ビットの符号付き整数、32 ビットの符号なし整数、単精度浮動小数点、倍精度浮動小数点の乱数を挿入します。間隔 [*l, *u] で均一に分布されるように、数値の増減や補正が行われます。
i_get_addrans_(x) は、x[0], ..., x[ADDRAN_SIZE-1] に i_addran_ で使用されているテーブルの現在の値を挿入します。i_set_addrans_(x) は、このテーブルに値 x[0], ..., x[ADDRAN_SIZE-1] を挿入します。i_init_addrans_() は、このテーブルを初期状態にリセットします。
r_get_addrans_(x) は、x[0], ..., x[ADDRAN_SIZE-1] に r_addran_ で使用されているテーブルの現在の値を挿入します。r_set_addrans_(x) は、このテーブルに値 x[0], ..., x[ADDRAN_SIZE-1] を挿入します。r_init_addrans_() は、このテーブルを初期状態にリセットします。
d_get_addrans_(x) は、x[0], ..., x[ADDRAN_SIZE-1] に d_addran_ で使用されているテーブルの現在の値を挿入します。d_set_addrans_(x) は、このテーブルに値 x[0], ..., x[ADDRAN_SIZE-1] を挿入します。d_init_addrans_() は、このテーブルを初期状態にリセットします。
i_addrans_ と u_addrans_ は、i_addran_ と同じテーブルを使用します。r_addrans_ は、r_addran_ と同じテーブルを使用します。d_addrans_ は、d_addran_ と同じテーブルを使用します。したがって、たとえば、i_init_addrans_ を呼び出した直後に i_addran_ を呼び出す場合と、i_init_addrans_、u_addrans_、i_addran_ の順に呼び出す場合では結果が異なります。ただし、プログラム内のスレッドごとに異なるテーブルを使用するため、これらの関数のいずれかをあるスレッドで呼び出すときに、同じ関数が別のスレッドから呼び出されても、生成される値は影響を受けません。
[0,1] で 1000 個の倍精度乱数を生成するには:
double x[1000]; int i; for (i = 0; i < 1000; i++) x[i] = d_addran_();
次の形式を使用すると、同じ数値をより効率的に生成できます。
double x[1000], lb, ub; int n = 1000; lb = D_ADDRAN_LB; /* defined in <sunmath.h> */ ub = D_ADDRAN_UB; /* defined in <sunmath.h> */ d_addrans_(x, &n, &lb, &ub);
-10 から 10 までの範囲で 1000 個の整数乱数を生成するには:
int x[1000], n = 1000, lb = -10, ub = 10; i_addrans_(x, &n, &lb, &ub);
次の属性については、attributes(5) を参照してください。
|
drand48(3C)、lcrans(3M)、mwcrans(3M)、rand(3C)、random(3C)、shufrans(3M)、attributes(5)
Knuth 著、『Seminumerical Algorithms』、1981 年、Addison-Wesley。
Park、Miller 共著、『Random Number Generators: Good Ones are Hard to Find』、Communications of the ACM、1988 年 10 月。
一般に、addrans(3M) ジェネレータは、lcrans(3M) または mwcrans(3M) ジェネレータよりも高速です。