[rand.eng]

# 29 Numerics library [[numerics]](./#numerics)

## 29.5 Random number generation [[rand]](rand#eng)

### 29.5.4 Random number engine class templates [rand.eng]

#### [29.5.4.1](#general) General [[rand.eng.general]](rand.eng.general)

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2595)

Each type instantiated
from a class template specified in [rand.eng]
meets the requirements
of a [random number engine](rand.req.eng "29.5.3.4 Random number engine requirements [rand.req.eng]") type[.](#general-1.sentence-1)

[2](#general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2601)

Except where specified otherwise,
the complexity of each function
specified in [rand.eng]
is constant[.](#general-2.sentence-1)

[3](#general-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2607)

Except where specified otherwise,
no function described in [rand.eng]
throws an exception[.](#general-3.sentence-1)

[4](#general-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2612)

Every function described in [rand.eng]
that has a function parameter q of type Sseq& for a template type parameter named Sseq that is different from type seed_seq throws what and when the invocation of q.generate throws[.](#general-4.sentence-1)

[5](#general-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2619)

Descriptions are provided in [rand.eng]
only for engine operations
that are not described in [[rand.req.eng]](rand.req.eng "29.5.3.4 Random number engine requirements") or for operations where there is additional semantic information[.](#general-5.sentence-1)

In particular,
declarations for copy constructors,
for copy assignment operators,
for streaming operators,
and for equality and inequality operators
are not shown in the synopses[.](#general-5.sentence-2)

[6](#general-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2631)

Each template specified in [rand.eng]
requires one or more relationships,
involving the value(s) of its constant template parameter(s), to hold[.](#general-6.sentence-1)

A program instantiating any of these templates
is ill-formed
if any such required relationship fails to hold[.](#general-6.sentence-2)

[7](#general-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2639)

For every random number engine and for every random number engine adaptor X defined in [rand.eng] and in [[rand.adapt]](rand.adapt "29.5.5 Random number engine adaptor class templates"):

- [(7.1)](#general-7.1)

if the constructortemplate<class Sseq> explicit X(Sseq& q); is called with a type Sseq that does not qualify as a seed sequence, then this
constructor shall not participate in overload resolution;

- [(7.2)](#general-7.2)

if the member functiontemplate<class Sseq> void seed(Sseq& q); is called with a type Sseq that does not qualify as a seed sequence, then this
function shall not participate in overload resolution[.](#general-7.sentence-1)

The extent to which an implementation determines that a type cannot be a seed sequence
is unspecified, except that as a minimum a type shall not qualify as a seed sequence
if it is implicitly convertible to X​::​result_type[.](#general-7.sentence-2)

#### [29.5.4.2](#lcong) Class template linear_congruential_engine [[rand.eng.lcong]](rand.eng.lcong)

[1](#lcong-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2670)

A linear_congruential_engine random number engine
produces unsigned integer random numbers[.](#lcong-1.sentence-1)

The state xi of a linear_congruential_engine object x is of size 1 and consists of a single integer[.](#lcong-1.sentence-2)

The transition algorithm
is a modular linear function of the formTA(xi)=(aâxi+c)modm;
the generation algorithm
is GA(xi)=xi+1[.](#lcong-1.sentence-3)

[ð](#lib:linear_congruential_engine_)

namespace std {template<class UIntType, UIntType a, UIntType c, UIntType m>class linear_congruential_engine {public:// typesusing result_type = UIntType; // engine characteristicsstatic constexpr result_type multiplier = a; static constexpr result_type increment = c; static constexpr result_type modulus = m; static constexpr result_type min() { return c == 0u ? 1u: 0u; }static constexpr result_type max() { return m - 1u; }static constexpr result_type default_seed = 1u; // constructors and seeding functions linear_congruential_engine() : linear_congruential_engine(default_seed) {}explicit linear_congruential_engine(result_type s); template<class Sseq> explicit linear_congruential_engine(Sseq& q); void seed(result_type s = default_seed); template<class Sseq> void seed(Sseq& q); // equality operatorsfriend bool operator==(const linear_congruential_engine& x, const linear_congruential_engine& y); // generating functions result_type operator()(); void discard(unsigned long long z); // inserters and extractorstemplate<class charT, class traits>friend basic_ostream<charT, traits>&operator<<(basic_ostream<charT, traits>& os, // hostedconst linear_congruential_engine& x); template<class charT, class traits>friend basic_istream<charT, traits>&operator>>(basic_istream<charT, traits>& is, // hosted linear_congruential_engine& x); };}

[2](#lcong-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2729)

If the template parameterm is 0,
the modulus m used throughout [[rand.eng.lcong]](#lcong "29.5.4.2 Class template linear_­congruential_­engine") is numeric_limits<result_type>​::​max() plus 1[.](#lcong-2.sentence-1)

[*Note [1](#lcong-note-1)*:

m need not be representable
 as a value of type result_type[.](#lcong-2.sentence-2)

â *end note*]

[3](#lcong-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2740)

If the template parameterm is not 0,
the following relations shall hold: a < m and c < m[.](#lcong-3.sentence-1)

[4](#lcong-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2748)

The textual representation
consists of
the value of xi[.](#lcong-4.sentence-1)

[ð](#lib:linear_congruential_engine,constructor)

`explicit linear_congruential_engine(result_type s);
`

[5](#lcong-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2759)

*Effects*: If cmodm is 0 and smodm is 0,
 sets the engine's state to 1,
 otherwise sets the engine's state to smodm[.](#lcong-5.sentence-1)

[ð](#lib:linear_congruential_engine,constructor_)

`template<class Sseq> explicit linear_congruential_engine(Sseq& q);
`

[6](#lcong-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2772)

*Effects*: With k=âlog2m32â and a an array (or equivalent)
 of length k+3,
 invokes q.generate(a+0, a+k+3) and then computes S=(âkâ1j=0aj+3â232j)modm[.](#lcong-6.sentence-1)

If cmodm is 0 and S is 0,
 sets the engine's state to 1,
 else sets the engine's state
 to S[.](#lcong-6.sentence-2)

#### [29.5.4.3](#mers) Class template mersenne_twister_engine [[rand.eng.mers]](rand.eng.mers)

[1](#mers-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2793)

A mersenne_twister_engine random number
engine[242](#footnote-242 "The name of this engine refers, in part, to a property of its period: For properly-selected values of the parameters, the period is closely related to a large Mersenne prime number.") produces unsigned integer random numbers
in the closed interval [0,2wâ1][.](#mers-1.sentence-1)

The
statexi of a mersenne_twister_engine object x is of size n and consists of a sequence X of n values of the type delivered by x;
all subscripts applied to X are to be taken modulo n[.](#mers-1.sentence-2)

[2](#mers-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2812)

The transition algorithm
employs a twisted generalized feedback shift register
defined by shift values n and m, a twist value r,
and a conditional xor-mask a[.](#mers-2.sentence-1)

To improve the uniformity of the result,
the bits of the raw shift register are additionally [*tempered*](#def:tempered) (i.e., scrambled) according to a bit-scrambling matrix
defined by values u, d, s, b, t, c, and â[.](#mers-2.sentence-2)

The state transition is performed as follows:

- [(2.1)](#mers-2.1)

  Concatenate
 the upper wâr bits of Xiân with
 the lower r bits of Xi+1ân to obtain an unsigned integer value Y[.](#mers-2.1.sentence-1)

- [(2.2)](#mers-2.2)

  With Î±=aâ(Ybitand1),
 set Xi to Xi+mânxor(Yrshift1)xorÎ±[.](#mers-2.2.sentence-1)

The sequence X is initialized
with the help of an initialization multiplier f[.](#mers-2.sentence-4)

[3](#mers-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2838)

The generation algorithm
 determines the unsigned integer values z1,z2,z3,z4 as follows,
 then delivers z4 as its result:

- [(3.1)](#mers-3.1)

  Let z1=Xixor((Xirshiftu)bitandd)[.](#mers-3.1.sentence-1)

- [(3.2)](#mers-3.2)

  Let z2=z1xor((z1lshiftws)bitandb)[.](#mers-3.2.sentence-1)

- [(3.3)](#mers-3.3)

  Let z3=z2xor((z2lshiftwt)bitandc)[.](#mers-3.3.sentence-1)

- [(3.4)](#mers-3.4)

  Let z4=z3xor(z3rshiftâ)[.](#mers-3.4.sentence-1)

[ð](#lib:mersenne_twister_engine_)

namespace std {template<class UIntType, size_t w, size_t n, size_t m, size_t r,
 UIntType a, size_t u, UIntType d, size_t s,
 UIntType b, size_t t,
 UIntType c, size_t l, UIntType f>class mersenne_twister_engine {public:// typesusing result_type = UIntType; // engine characteristicsstatic constexpr size_t word_size = w; static constexpr size_t state_size = n; static constexpr size_t shift_size = m; static constexpr size_t mask_bits = r; static constexpr UIntType xor_mask = a; static constexpr size_t tempering_u = u; static constexpr UIntType tempering_d = d; static constexpr size_t tempering_s = s; static constexpr UIntType tempering_b = b; static constexpr size_t tempering_t = t; static constexpr UIntType tempering_c = c; static constexpr size_t tempering_l = l; static constexpr UIntType initialization_multiplier = f; static constexpr result_type min() { return 0; }static constexpr result_type max() { return 2wâ1; }static constexpr result_type default_seed = 5489u; // constructors and seeding functions mersenne_twister_engine() : mersenne_twister_engine(default_seed) {}explicit mersenne_twister_engine(result_type value); template<class Sseq> explicit mersenne_twister_engine(Sseq& q); void seed(result_type value = default_seed); template<class Sseq> void seed(Sseq& q); // equality operatorsfriend bool operator==(const mersenne_twister_engine& x, const mersenne_twister_engine& y); // generating functions result_type operator()(); void discard(unsigned long long z); // inserters and extractorstemplate<class charT, class traits>friend basic_ostream<charT, traits>&operator<<(basic_ostream<charT, traits>& os, // hostedconst mersenne_twister_engine& x); template<class charT, class traits>friend basic_istream<charT, traits>&operator>>(basic_istream<charT, traits>& is, // hosted mersenne_twister_engine& x); };}

[4](#mers-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2911)

The following relations shall hold: 0 < m, m <= n, 2u < w, r <= w, u <= w, s <= w, t <= w, l <= w, w <= numeric_limits<UIntType>​::​digits, a <= (1u << w) - 1u, b <= (1u << w) - 1u, c <= (1u << w) - 1u, d <= (1u << w) - 1u,
and f <= (1u << w) - 1u[.](#mers-4.sentence-1)

[5](#mers-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2929)

The textual representation
of xi consists of the values of Xiân,â¦,Xiâ1,
in that order[.](#mers-5.sentence-1)

[ð](#lib:mersenne_twister_engine,constructor)

`explicit mersenne_twister_engine(result_type value);
`

[6](#mers-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2941)

*Effects*: Sets Xân to valuemod2w[.](#mers-6.sentence-1)

Then, iteratively for i=1ân,â¦,â1, sets Xi to  
[fâ(Xiâ1xor(Xiâ1rshift(wâ2)))+imodn]mod2w[.](#mers-6.sentence-2)

[7](#mers-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2954)

*Complexity*: O(n)[.](#mers-7.sentence-1)

[ð](#lib:mersenne_twister_engine,constructor_)

`template<class Sseq> explicit mersenne_twister_engine(Sseq& q);
`

[8](#mers-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2965)

*Effects*: With k=âw/32â and a an array (or equivalent)
 of length nâk,
 invokes q.generate(a+0, a+nâk) and then, iteratively for i=ân,â¦,â1,
 sets Xi to (âkâ1j=0ak(i+n)+jâ232j)mod2w[.](#mers-8.sentence-1)

Finally,
 if the most significant wâr bits of Xân are zero,
 and if each of the other resulting Xi is 0,
 changes Xân to 2wâ1[.](#mers-8.sentence-2)

[242)](#footnote-242)[242)](#footnoteref-242)

The name of this engine refers, in part, to a property of its period:
 For properly-selected values of the parameters,
 the period is closely related to a large Mersenne prime number[.](#footnote-242.sentence-1)

#### [29.5.4.4](#sub) Class template subtract_with_carry_engine [[rand.eng.sub]](rand.eng.sub)

[1](#sub-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2989)

A subtract_with_carry_engine random number engine
produces unsigned integer random numbers[.](#sub-1.sentence-1)

[2](#sub-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L2993)

The state xi of a subtract_with_carry_engine object x is of sizeO(r),
and consists of
a sequence X of r integer values 0â¤Xi<m=2w;
all subscripts applied to X are to be taken modulo r[.](#sub-2.sentence-1)

The state xi additionally consists of an integer c (known as the [*carry*](#def:carry))
whose value is either 0 or 1[.](#sub-2.sentence-2)

[3](#sub-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3006)

The state transition
is performed as follows:

- [(3.1)](#sub-3.1)

  Let Y=XiâsâXiârâc[.](#sub-3.1.sentence-1)

- [(3.2)](#sub-3.2)

  Set Xi to y=Ymodm[.](#sub-3.2.sentence-1)
  Set c to 1 if Y<0,
 otherwise set c to 0[.](#sub-3.2.sentence-2)

[*Note [1](#sub-note-1)*:

This algorithm corresponds
 to a modular linear function
 of the form TA(xi)=(aâxi)modb,
 where b is of the form mrâms+1 and a=bâ(bâ1)/m[.](#sub-3.sentence-2)

â *end note*]

[4](#sub-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3027)

The generation algorithm
is given by GA(xi)=y,
where y is the value produced as a result
of advancing the engine's state as described above[.](#sub-4.sentence-1)

[ð](#lib:subtract_with_carry_engine_)

namespace std {template<class UIntType, size_t w, size_t s, size_t r>class subtract_with_carry_engine {public:// typesusing result_type = UIntType; // engine characteristicsstatic constexpr size_t word_size = w; static constexpr size_t short_lag = s; static constexpr size_t long_lag = r; static constexpr result_type min() { return 0; }static constexpr result_type max() { return mâ1; }static constexpr uint_least32_t default_seed = 19780503u; // constructors and seeding functions subtract_with_carry_engine() : subtract_with_carry_engine(0u) {}explicit subtract_with_carry_engine(result_type value); template<class Sseq> explicit subtract_with_carry_engine(Sseq& q); void seed(result_type value = 0u); template<class Sseq> void seed(Sseq& q); // equality operatorsfriend bool operator==(const subtract_with_carry_engine& x, const subtract_with_carry_engine& y); // generating functions result_type operator()(); void discard(unsigned long long z); // inserters and extractorstemplate<class charT, class traits>friend basic_ostream<charT, traits>&operator<<(basic_ostream<charT, traits>& os, // hostedconst subtract_with_carry_engine& x); template<class charT, class traits>friend basic_istream<charT, traits>&operator>>(basic_istream<charT, traits>& is, // hosted subtract_with_carry_engine& x); };}

[5](#sub-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3079)

The following relations shall hold: 0u < s, s < r, 0 < w,
and w <= numeric_limits<UIntType>​::​digits[.](#sub-5.sentence-1)

[6](#sub-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3087)

The textual representation
consists of the values of Xiâr,â¦,Xiâ1,
in that order, followed by c[.](#sub-6.sentence-1)

[ð](#lib:subtract_with_carry_engine,constructor)

`explicit subtract_with_carry_engine(result_type value);
`

[7](#sub-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3099)

*Effects*: Sets the values of Xâr,â¦,Xâ1,
 in that order, as specified below[.](#sub-7.sentence-1)

If Xâ1 is then 0,
 sets c to 1;
 otherwise sets c to 0[.](#sub-7.sentence-2)

To set the values Xk,
 first construct e, a linear_congruential_engine object,
 as if by the following definition:linear_congruential_engine<uint_least32_t, 40014u, 0u, 2147483563u> e( value == 0u ? default_seed : static_cast<uint_least32_t>(value % 2147483563u));

Then, to set each Xk,
 obtain new values z0,â¦,znâ1 from n=âw/32â successive invocations
 of e[.](#sub-7.sentence-4)

Set Xk to (ânâ1j=0zjâ232j)modm[.](#sub-7.sentence-5)

[8](#sub-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3121)

*Complexity*: Exactly nâr invocations
 of e[.](#sub-8.sentence-1)

[ð](#lib:subtract_with_carry_engine,constructor_)

`template<class Sseq> explicit subtract_with_carry_engine(Sseq& q);
`

[9](#sub-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3133)

*Effects*: With k=âw/32â and a an array (or equivalent)
 of length râk,
 invokes q.generate(a+0, a+râk) and then, iteratively for i=âr,â¦,â1,
 sets Xi to (âkâ1j=0ak(i+r)+jâ232j)modm[.](#sub-9.sentence-1)

If Xâ1 is then 0,
 sets c to 1;
 otherwise sets c to 0[.](#sub-9.sentence-2)

#### [29.5.4.5](#philox) Class template philox_engine [[rand.eng.philox]](rand.eng.philox)

[1](#philox-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3154)

A philox_engine random number engine produces
unsigned integer random numbers in the interval [0, m),
where m=2w and
the template parameter w defines the range of the produced numbers[.](#philox-1.sentence-1)

The state of a philox_engine object consists of
a sequence X of n unsigned integer values of width w,
a sequence K of n/2 values of result_type,
a sequence Y of n values of result_type, and
a scalar i, where

- [(1.1)](#philox-1.1)

X is the interpretation of the unsigned integer [*counter*](#def:counter) valueZ:=ânâ1j=0Xjâ2wj of nâw bits,

- [(1.2)](#philox-1.2)

K are keys, which are generated once from the seed (see constructors below)
and remain constant unless the seed function ([[rand.req.eng]](rand.req.eng "29.5.3.4 Random number engine requirements")) is invoked,

- [(1.3)](#philox-1.3)

Y stores a batch of output values, and

- [(1.4)](#philox-1.4)

i is an index for an element of the sequence Y[.](#philox-1.sentence-2)

[2](#philox-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3177)

The generation algorithm returns Yi,
the value stored in the ith element of Y after applying
the transition algorithm[.](#philox-2.sentence-1)

[3](#philox-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3182)

The state transition is performed as if by the following algorithm:i = i + 1if (i == n) {Y = Philox(K, X) // *see below*Z = Z + 1i = 0}

[4](#philox-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3193)

The Philox function maps the length-n/2 sequence K and
the length-n sequence X into a length-n output sequence Y[.](#philox-4.sentence-1)

Philox applies an r-round substitution-permutation network to the values in X[.](#philox-4.sentence-2)

A single round of the generation algorithm performs the following steps:

- [(4.1)](#philox-4.1)

The output sequence Xâ² of the previous round
(X in case of the first round)
is permuted to obtain the intermediate state V:Vj=Xâ²fn(j) where j=0,â¦,nâ1 andfn(j) is defined in Table [129](#tab:rand.eng.philox.f "Table 129: Values for the word permutation <b>f</b>ï¿½"). Table [129](#tab:rand.eng.philox.f) — Values for the word permutation fn(j) [[tab:rand.eng.philox.f]](./tab:rand.eng.philox.f)  

| [ð](#tab:rand.eng.philox.f-row-1)<br>fn(j) | | **j** | | | |
| --- | --- | --- | --- | --- | --- |
| [ð](#tab:rand.eng.philox.f-row-2) | | 0 | 1 | 2 | 3 |
| [ð](#tab:rand.eng.philox.f-row-3)<br>**n** | 2 | 0 | 1 |  | |
| [ð](#tab:rand.eng.philox.f-row-4)<br> | 4 | 2 | 1 | 0 | 3 |
| [ð](#tab:rand.eng.philox.f-row-5)<br> |

  [*Note [1](#philox-note-1)*:
  For n=2 the sequence is not permuted[.](#philox-4.1.sentence-2)
 â *end note*]

- [(4.2)](#philox-4.2)

The following computations are applied to the elements of the V sequence:X2k+0=mulhi(V2k,Mk,w)xorkeyqkxorV2k+1X2k+1=mullo(V2k,Mk,w) where:
  * [(4.2.1)](#philox-4.2.1)

mullo(a, b, w) is
 the low half of the modular multiplication of a and b: (aâb)mod2w,

  * [(4.2.2)](#philox-4.2.2)

mulhi(a, b, w) is
 the high half of the modular multiplication of a and b: (â(aâb)/2wâ),

  * [(4.2.3)](#philox-4.2.3)

k=0,â¦,n/2â1 is the index in the sequences,

  * [(4.2.4)](#philox-4.2.4)

q=0,â¦,râ1 is the index of the round,

  * [(4.2.5)](#philox-4.2.5)

keyqk is the kth round key for round q, keyqk:=(Kk+qâCk)mod2w,

  * [(4.2.6)](#philox-4.2.6)

Kk are the elements of the key sequence K,

  * [(4.2.7)](#philox-4.2.7)

Mk is multipliers[k], and

  * [(4.2.8)](#philox-4.2.8)

Ck is round_consts[k].

[5](#philox-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3261)

After r applications of the single-round function,Philox returns the sequence Y=Xâ²[.](#philox-5.sentence-1)

[ð](#lib:philox_engine_)

namespace std {template<class UIntType, size_t w, size_t n, size_t r, UIntType... consts>class philox_engine {static constexpr size_t *array-size* = n / 2; // *exposition only*public:// typesusing result_type = UIntType; // engine characteristicsstatic constexpr size_t word_size = w; static constexpr size_t word_count = n; static constexpr size_t round_count = r; static constexpr array<result_type, *array-size*> multipliers; static constexpr array<result_type, *array-size>* round_consts; static constexpr result_type min() { return 0; }static constexpr result_type max() { return m - 1; }static constexpr result_type default_seed = 20111115u; // constructors and seeding functions philox_engine() : philox_engine(default_seed) {}explicit philox_engine(result_type value); template<class Sseq> explicit philox_engine(Sseq& q); void seed(result_type value = default_seed); template<class Sseq> void seed(Sseq& q); void set_counter(const array<result_type, n>& counter); // equality operatorsfriend bool operator==(const philox_engine& x, const philox_engine& y); // generating functions result_type operator()(); void discard(unsigned long long z); // inserters and extractorstemplate<class charT, class traits>friend basic_ostream<charT, traits>&operator<<(basic_ostream<charT, traits>& os, const philox_engine& x); // hostedtemplate<class charT, class traits>friend basic_istream<charT, traits>&operator>>(basic_istream<charT, traits>& is, philox_engine& x); // hosted};}

[6](#philox-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3313)

*Mandates*: 

- [(6.1)](#philox-6.1)

sizeof...(consts) == n is true, and

- [(6.2)](#philox-6.2)

n == 2 || n == 4 is true, and

- [(6.3)](#philox-6.3)

0 < r is true, and

- [(6.4)](#philox-6.4)

0 < w && w <= numeric_limits<UIntType>​::​digits is true[.](#philox-6.sentence-1)

[7](#philox-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3322)

The template parameter pack consts represents
the Mk and Ck constants which are grouped as follows:[M0,C0,M1,C1,M2,C2,â¦,Mn/2â1,Cn/2â1][.](#philox-7.sentence-1)

[8](#philox-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3327)

The textual representation consists of the values ofK0,â¦,Kn/2â1,X0,â¦,Xnâ1,i, in that order[.](#philox-8.sentence-1)

[*Note [2](#philox-note-2)*:

The stream extraction operator can reconstruct Y from K and X, as needed[.](#philox-8.sentence-2)

â *end note*]

[ð](#lib:philox_engine,constructor)

`explicit philox_engine(result_type value);
`

[9](#philox-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3340)

*Effects*: Sets the K0 element of sequence K to valuemod2w[.](#philox-9.sentence-1)

All elements of sequences X and K (except K0) are set to 0[.](#philox-9.sentence-2)

The value of i is set to nâ1[.](#philox-9.sentence-3)

[ð](#lib:philox_engine,constructor_)

`template<class Sseq> explicit philox_engine(Sseq& q);
`

[10](#philox-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3353)

*Effects*: With p=âw/32â and
an array (or equivalent) a of length (n/2)âp,
invokes q.generate(a + 0, a + n / 2 * p) and
then iteratively for k=0,â¦,n/2â1,
sets Kk to(âpâ1j=0akp+jâ232j)mod2w[.](#philox-10.sentence-1)

All elements of sequence X are set to 0[.](#philox-10.sentence-2)

The value of i is set to nâ1[.](#philox-10.sentence-3)

[ð](#lib:set_counter,philox_engine)

`void set_counter(const array<result_type, n>& c);
`

[11](#philox-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L3371)

*Effects*: For j=0,â¦,nâ1 sets Xj to Cnâ1âjmod2w[.](#philox-11.sentence-1)

The value of i is set to nâ1[.](#philox-11.sentence-2)

[*Note [3](#philox-note-3)*:

The counter is the value Z introduced at the beginning of this subclause[.](#philox-11.sentence-3)

â *end note*]
