= 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 the http://www.math.sci.hiroshima-u.ac.jp/m-mat/MT/emt.html[
_Mersenne Twister_ algorithm].  The implementation is specialized
to the native word size.  In the description below, we assume that
the default word and integer types (`Word.word` and `Int.int`)
have a representation that is smaller than the native size
(_e.g._, 63 or 32 bits on a 64-bit machine).

Note that prior to 2023.1 (and 110.99.4), this structure was implemented
using a _subtract-with-borrow_ algorithm.

== Synopsis

[source,sml]
------------
structure Random :> RANDOM
------------

== Interface

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

val rand : (int * int) -> rand

val fromList : NativeWord.word list -> rand

val toBytes : rand -> Word8Vector.vector
val fromBytes : Word8Vector.vector -> rand

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

val randNativeInt : rand -> NativeInt.int

val randNativeWord : rand -> NativeWord.word

val randInt : rand -> int

val randWord : 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)`.
  This function is kept for backward compatibility with the old
  implementation, but it is recommended that one use the `fromList`
  function in new code.

`[.kw]#val# fromList : NativeWord.word list \-> rand`::
  creates a random number generator from the given list of initial seeds.

`[.kw]#val# toBytes : rand \-> Word8Vector.vector`::
  `toBytes rand` returns a byte vector representing the current state of
  the generator.

`[.kw]#val# fromBytes : Word8Vector.vector \-> rand`::
  `fromBytes bv` creates a generator with the initial state that was encoded
  in the byte vector `bv`.  This expression will raise
  {sml-basis-url}/general.html#SIG:GENERAL.Fail:EXN[`Fail`] exception
  if the byte vector is invalid.

`[.kw]#val# toString : rand \-> string`::
  `toString rand` returns a string representing the random-number-generator
  state `rand`.  This string is a xref:str-Base64.adoc[`Base64`] encoding
  of the result of `toBytes rand`.

`[.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# randNativeWord : rand \-> NativeWord.word`::
  `randNativeWord rand` generates a uniform random number in the range
  latexmath:[[0 .. 2^k-1]], where latexmath:[k] is the host platform's
  native word size (__e.g.__, 32 or 64).

`[.kw]#val# randNativeInt : rand \-> NativeInt.int`::
  `randNativeInt rand` generates a random word a uniform distribution in
  the range latexmath:[[0 .. 2^{k-1}-1]], where latexmath:[k] is the host
  platform's native word size (__e.g.__, 32 or 64).

`[.kw]#val# randInt : rand \-> int`::
  `randInt rand` generates a random integer with a uniform distribution in
  the range latexmath:[[-2^{k-1} .. 2^{k-1}-1]], where latexmath:[k]
  is the size of the `Int.int` type.

`[.kw]#val# randWord : rand \-> word`::
  `randWord rand` generates a random word with a uniform distribution in
  the range latexmath:[[0 .. 2^k-1]], where latexmath:[k]
  is the number of bits in the `Word.word` type.

`[.kw]#val# randNat : rand \-> int`::
  `randNat rand` generates a random integer with a uniform distribution in
  the range latexmath:[[0 .. 2^{k-1}-1]], where latexmath:[k]
  is the number of bits in the `Int.int` type.

`[.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`.

== See Also

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