MersenneTwister
use strict; | |
# MT19937 | |
my $w = 32; | |
my $n = 624; | |
my $m = 397; | |
my $r = 31; | |
my $u = 11; | |
my $s = 7; | |
my $t = 15; | |
my $l = 18; | |
my $a = 0x9908B0DF; | |
my $b = 0x9D2C5680; | |
my $c = 0xEFC60000; | |
# MT内部状態 | |
my $i = 0; | |
my @x = (); | |
# ビットマスクの準備 | |
my $mask_u = 0; | |
my $mask_l = 0; | |
for(my $j = 0; $j < $w; $j++){ | |
$mask_u = ($mask_u << 1) + ($j < $w - $r); | |
$mask_l = ($mask_l << 1) + ($j >= $w - $r); | |
} | |
# seedを受け取ってxを初期化 (mt19937ar.cに準拠) | |
sub init_genrand { | |
my($seed) = @_; | |
$x[0] = $seed & 0xFFFFFFFF; | |
for(my $j = 1; $j < $n; $j++){ | |
$x[$j] = (1812433253 * ($x[$j-1] ^ ($x[$j-1] >> 30)) + $j) & 0xFFFFFFFF; | |
} | |
} | |
# 乱数を生成 | |
sub genrand_int { | |
# Step.1 | |
my $z = ($x[$i] & $mask_u | $x[($i+1) % $n] & $mask_l); | |
# Step.2 | |
$x[$i] = $x[($i+$m) % $n] ^ ($z >> 1) ^ (($z & 1) == 0 ? 0 : $a); | |
# Step.3 | |
my $y = $x[$i]; | |
$y = $y ^ ($y >> $u); | |
$y = $y ^ (($y << $s) & $b); | |
$y = $y ^ (($y << $t) & $c); | |
$y = $y ^ ($y >> $l); | |
# カウンタを変更して、生成した乱数を返す | |
$i = ($i+1) % $n; | |
return $y; | |
} | |
# 使ってみる | |
init_genrand(20150919); | |
for(my $j = 1; $j <= 1024; $j++){ | |
print $j, ": ", genrand_int(), "\n"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment