= The `Random` structure
:Author: John Reppy
:Date: {release-date}
:stem: latexmath
:source-highlighter: pygments
:VERSION: {smlnj-version}

The `Random` structure implements a random number generator using a
__subtract-with-borrow__ (SWB) generator as described in Marsaglia
and Zaman, "https://doi.org/10.1214/aoap/1177005878[__A New Class of
Random Number Generators__]," Annuals of Applied Probability 1(3), 1991,
pp. 462-480.

The SWB generator is a 31-bit generator with lags 48 and 8. It has period
(2^1487^ - 2^247^) / 105 or about 10^445^. In general, these generators are
excellent. They act locally like a lagged Fibonacci generator. however,
and thus have troubles with the birthday test. Thus, we combine this SWB
generator with the linear congruential generator (48271 \* a) mod (2^31^ - 1).

Although the interface is fairly abstract, the implementation uses
31-bit ML words. At some point, it might be good to use 32-bit words.

== Synopsis

[source,sml]
------------
structure Random
------------

== Interface

[source,sml]
------------
type rand

val rand : (int * int) -> rand

val toString : rand -> string
val fromString : string -> rand

val randInt : rand -> int

val randNat : rand -> int

val randReal : rand -> real

val randRange : (int * int) -> rand -> int
------------

== Description

`[.kw]#type# rand`::
  Represents the internal state of a random number generator.

`[.kw]#val# rand : (int * int) \-> rand`::
  `rand (n1, n2)` creates a random number generator from the
  initial seed specified by the pair `(n1, n2)`.

`[.kw]#val# toString : rand \-> string`::
  `toString rand` returns a string representing the random-number-generator
  state `rand`.  This string is not meant to be human readable and will likely
  contain non-printable characters.

`[.kw]#val# fromString : string \-> rand`::
  `fromString s` returns the random-number-generator encoded as the string `s`
  (presumably generated by `toString`).  This expression will raise
  {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`] exception
  if the string `s` does not have the proper form.

`[.kw]#val# randInt : rand \-> int`::
  `randInt rand` generates a random integer with a uniform distribution in
  the range `[minInt .. maxInt]`.
+
[WARNING]
The range of values is for 32-bit machines.

`[.kw]#val# randNat : rand \-> int`::
  `randInt rand` generates a random integer with a uniform distribution in
  the range `[0 .. maxInt]`.
+
[WARNING]
The range of values is for 32-bit machines.

`[.kw]#val# randReal : rand \-> real`::
  `randReal rand` generates a random real number in the range `[0..1)`.

`[.kw]#val# randRange : (int * int) \-> rand \-> int`::
  `randRange (lo, hi) rand` generates a random number in the
  `[lo..hi]`.  This function will raise the
  {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`] exception
  if `hi < lo`.

== Bugs

The `toString`/`fromString` functions should be replaced with functions
that encode the state as a `Word8Vector.vector`.

This implementation needs to be updated for 64-bit systems.

== See Also

xref:str-Rand.adoc[`Rand`],
xref:smlnj-lib.adoc[__The Util Library__]
