## rand.pkg
# Compiled by:
#
src/lib/std/standard.lib# Random number generator taken from Paulson, pages 170-171.
# Recommended by Stephen K. Park and Keith W. Miller,
# Random number generators: good ones are hard to find,
# CACM 31 (1988), 1192-1201
# Updated to include the new preferred multiplier of 48271
# CACM 36 (1993), 105-110
# Updated to use on tagged_unt.
#
# Note: The Random package provides a better generator.
### "The generation of random numbers is
### too important to be left to chance."
###
### -- Robert Coveyou
### "We must believe in luck.
### For how else can we explain the
### success of those we don't like?"
###
### -- Jean Cocteau
stipulate
package f8b = eight_byte_float; # eight_byte_float is from
src/lib/std/eight-byte-float.pkgherein
package rand
: (weak) Rand # Rand is from
src/lib/src/rand.api {
Rand = tagged_unt::Unt;
Rand' = one_word_int::Int; # internal representation
my a: Rand' = 48271;
my m: Rand' = 2147483647; # 2^31 - 1
m_1 = m - 1;
q = m / a;
r = m % a;
ext_to_int = one_word_int::from_multiword_int o tagged_unt::to_multiword_int;
int_to_ext = tagged_unt::from_multiword_int o one_word_int::to_multiword_int;
my rand_min: Rand = 0u1;
my rand_max: Rand = int_to_ext m_1;
fun check 0u0 => 1;
check 0ux7fffffff => m_1;
check seed => ext_to_int seed;
end;
fun random' seed
=
{ hi = seed / q;
lo = seed % q;
test = a * lo - r * hi;
test > 0 ?? test
:: test + m;
};
random = int_to_ext o random' o check;
fun make_random seed
=
{ seed = REF (check seed);
{. seed := random' *seed;
int_to_ext *seed;
};
};
float_m = f8b::from_multiword_int (one_word_int::to_multiword_int m);
fun normalize s
=
(f8b::from_multiword_int (tagged_unt::to_multiword_int s)) / float_m;
fun range (i, j)
=
if (j < i)
#
lib_base::failure { module=>"Random", fn=>"range", msg=>"hi < lo"};
elif (j == i)
\\ _ = i;
else
rrr = one_word_int::from_int j - one_word_int::from_int i;
convert = tagged_unt::to_int_x o tagged_unt::from_multiword_int o one_word_int::to_multiword_int;
if (rrr == m) tagged_unt::to_int_x;
else \\ s = i + convert ((ext_to_int s) % (rrr+1));
fi;
fi;
}; # rand
end;
## COPYRIGHT (c) 1991 by AT&T Bell Laboratories. See SMLNJ-COPYRIGHT file for details.
## COPYRIGHT (c) 1998 by AT&T Laboratories. See SMLNJ-COPYRIGHT file for details.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.