Dart: Structured web apps [8] random

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);
}

同じタグの記事: Dart
同じタグの記事: dartlang
同じカテゴリの記事: Program