Dartの乱数生成について調べてみました。Math.random() を使えば良いようですが、自分で実装した方が良い場合もあるかもしれません。
サイコロがわかりやすいと思うので、1から6までの乱数を1000回生成して、それぞれがどれくらい発生したのかをカウントしてみました。RandIntImple1, RandIntImple2 はDartのMath.random()を使って0.0以上 0.1未満のdouble型値(APIによると、Returns a random double greater than or equal to 0.0 and less than 1.0.)を出してから、その後の計算を変えています。RandIntImple3はよくある線形合同法によるもので、RandIntImple4はxorshiftによるものです。RandIntImple3, RandIntImple4 の計算には時間がかかる場合があります。
interface RandInt {
int random();
}
class RandIntImple1 implements RandInt {
int min = 0;
int max = 1;
RandIntImple1() {
}
RandIntImple1.minmax(this.min, this.max);
int random() {
double r = Math.random() * (max - min + 1) + min;
return r.toInt();
}
}
class RandIntImple2 extends RandIntImple1 implements RandInt {
RandIntImple2.minmax(int min, int max) : super.minmax(min, max);
int random() {
double r = min + (Math.random() * max).floor();
return r.toInt();
}
}
// rand
class RandIntImple3 extends RandIntImple1 implements RandInt {
RandIntImple3.minmax(int min, int max) : super.minmax(min, max);
static num x = 1;
void srand(num s) {
x = s;
}
num rand() {
x = x * 1103515245 + 12345;
return x & 2147483647;
}
int random() {
num r = rand();
return (min + r) % max + min;
}
}
class RandIntImple4 extends RandIntImple1 implements RandInt {
static num x = 123456789;
static num y = 362436069;
static num z = 521288629;
static num w = 88675123;
RandIntImple4.minmax(int min, int max) : super.minmax(min, max);
void seed(num x0, num y0, num z0, num w0) {
x = x0;
y = y0;
z = z0;
w = w0;
if (x+y+z+w <= 0) {
x = 123456789;
y = 362436069;
z = 521288629;
w = 88675123;
}
}
int random() {
num r = xor128();
return (min + r) % max + min;
}
num xor128(){
num t;
t = (x^(x<<11));
x = y;
y = z;
z = w;
w = (w^(w>>19))^(t^(t>>8));
return w;
}
}
void printRand(RandInt app) {
List result = new List(7);
for (int i=0 ; i<result.length ; i++) {
result[i] = 0;
}
for (int i=0 ; i<10000 ; i++) {
int x = app.random();
result[x]++;
}
result.forEach((e) => print(e));
int sum = 0;
result.forEach((e) => sum += e);
print(sum/6);
}
void main() {
printRand(new RandIntImple1.minmax(1, 6));
print("-----");
printRand(new RandIntImple2.minmax(1, 6));
print("-----");
RandIntImple3 rand3 = new RandIntImple3.minmax(1, 6);
int seed = (new Date.now()).value;
rand3.srand(seed);
printRand(rand3);
print("-----");
printRand(new RandIntImple4.minmax(1, 6));
print("-----");
RandIntImple4 rand4 = new RandIntImple4.minmax(1, 6);
rand4.seed(1, 10, 100, 1000);
printRand(rand4);
}
- クラスベースのオブジェクト指向プログラミング言語の基礎を学ぶには … 改訂版 基礎Java(CD-ROM付) (IMPRESS KISO SERIES)
- クラスベースのオブジェクト指向プログラミング言語を学ぶには … プログラミング言語Java (The Java Series)
- 関数型プログラミング言語を学ぶには … Scalaスケーラブルプログラミング第2版
- プログラミング言語の理論を学には … プログラミング言語の基礎概念 (ライブラリ情報学コア・テキスト)