Package: src/packages/random.fdoc
Random Number generators¶
key | file |
---|---|
random.flx | share/lib/std/random.flx |
Random number generation¶
Based on C++ Standard.
//[random.flx]
class Random {
private type random_device = "::std::random_device*"
requires Cxx11_headers::random;
private type random_engine = "::std::default_random_engine*"
requires Cxx11_headers::random;
private ctor random_device: 1 = "new ::std::random_device{}";
private ctor random_engine: random_device =
"new ::std::default_random_engine{(*$1)()}";
private gen generate_canonical: random_engine -> double =
"::std::generate_canonical<double, ::std::numeric_limits<float>::digits>(*$1)"
requires Cxx_headers::limits;
private struct random_ctl {
rd: random_device;
e: random_engine;
}
type random = new random_ctl;
ctor random() => let rd = #random_device in
_make_random$ random_ctl (rd, rd.random_engine);
private gen range[I in ints]: random_engine * I * I -> I =
"::std::uniform_int_distribution<decltype($2)>{$2, $3-1}(*$1)";
gen range[I in ints](r: random)(start: I, stop: I) =>
range (r._repr_.e, start, stop);
gen range[I in ints](r: random)(stop: I): I =>
r.range (C_hack::cast[I] 0, stop);
gen randint[I in ints with FloatAddgrp[I]](r: random)(start: I, stop: I) =>
r.range (start, stop+C_hack::cast[I] 1);
gen choice[T,S with ArrayValue[S,T]](r: random)(seq: S): T =>
unsafe_get (seq, r.range seq.len);
gen randflt(r: random) => r._repr_.e.generate_canonical;
proc shuffle[T,S with ArrayObject[S,T]](r: random)(seq: S) {
for var i in 0zu upto seq.len - 2 do
j := r.randint (0zu, i);
ei := unsafe_get (seq, i);
ej := unsafe_get (seq, j);
unsafe_set (seq, i, ej);
unsafe_set (seq, j, ei);
done
}
}