# A TR1 Tutorial: Generating Random Numbers

TR1 brings a new header into the standard library. called <random>. It defines several random number generators. Until TR1, the only way to generate random numbers in C++ was by using the rand() function. This function, although quite trivial to use and good enough for most of the applications, is not suitable for some applications. For them, developers had to rely on third-party libraries or generators, such as the Marsenne Twister. TR1 defines several good random generators, including the Marsenne twister.

Unfortunately, documentation for these generators is not very good, and MSDN lacks in examples. In this article, I will try to clarify how to use these generators, at least for simple usage.

### What Is a Generator?

A random number generator, contrary to a first impression, does not generate truly random numbers, but pseudo-random. Generating numbers imply executing an algorithm, each new number depending one way or another on the last generator number (or a number or more from previous iterations). That means any such algorithm needs an initial value, called a "seed." An algorithm initialized with the same seed will generate the same sequence of numbers. This is an important aspect because, in practice people, forget to initialize the generator. Being an algorithm based on formulas, a generator is deterministic, and the number it generates is also deterministic. Only a hardware device can generate truly random numbers.

### Before TR1

As I mentioned before, until TR1, the only "standard" way for generating random numbers was by using the rand() function. The following example shows how to generate numbers in the interval [0, 9].

```int main()
{
// seeding the generator
srand((unsigned int)time(NULL));

// generate 10 "random" numbers
for(int i = 0; i < 10; ++i)
{
std::cout << rand()%10 << " ";
}
std::cout << std::endl;

return 0;
}
```

The first step was to initialize the generator; a common practice (and probably the best) is to use the value returned by the time() function, which is the number of seconds passed since January 1, 1970. If this seeding is forgotten, all the generated sequences will be identical (each time you run the program, the same numbers will be generated).

You also have to pay attention not to call srand(), as shown above, twice in less than a second because, in that case, time() returns the same value and you run into the same problem.

### What's New in TR1?

TR1 introduces three types of 'entities': generators, engines, and distributions. A generator is an object that generates pseudo-random numbers. A generator that generates numbers with a uniform distribution is called an engine. Engines and distributions can be combined to generate numbers in two ways:

• Providing an engine to the operator() of a distribution class, or
• Using the variate_generator class to associate a generator and a distribution

### Engines

An engine is basically a data source of uniformly distributed numbers in a specific interval. All engines provide the following functions:

• min(): Gives the minimum value that can be returned by engine's operator();
• max(): Gives the maximum value that can be returned by engine's operator();
• operator(): Returns values uniformly distributed between min() and max();
• seed(): Initializes the engine with a start value; this function is missing from random_device.

There are two types of engines: simple and combined.

#### Simple engines

• linear_congruential: A linear congruential generator, generating numbers by using this forumula:
• `x(i) = (A * x(i-1) + C) mod M`
• marsenne_twister: An implementation of the Marsenne twister. This generator keeps a value on W * (N-1) * R bits; each time a number needs to be generated, it extracts W bits. When all bits have been used it, twists the large value by shifting and mixing the bits so that it has a new set of bits to extract from.
• subtract_with_carry: Generates numbers based on the following formula:
• `x(i) = (x(i - R) - x(i - S) - cy(i - 1)) mod M`
where
`cy(i) = x(i - S) - x(i - R) - cy(i - 1) < 0 ? 1 : 0`
• subtract_with_carry_01: Generates numbers based on the following formula:
• `x(i) = (x(i - R) - x(i - S) - cy(i - 1)) mod 1`
where
`cy(i) = if x(i - S) - x(i - R) - cy(i - 1) < 0 ? 2-W : 0`
• random_device: Generates random numbers by using an external device.

#### Combined engines

• xor_combine: Generates numbers by using two engines; the numbers produced by these two wrapped engines are shifted and composed using this formula:
• `x(i) = (eng1(i) << S1) ^ (eng2(i) << S2)`
• discard_block: Uses another engine to produce numbers; some of these are discarded. The engine is parameterized with another engine, the length of the used sequence (P) and the length of the discarded sequence (R). The generated returns a new number at the first R calls. Then, it generates another P-R numbers that are discarded, and the process is repeated.

#### typedefs for these engines

• minstd_rand0: Linear congruential generator
• ```typedef linear_congruential<unsigned long, 16807, 0,
2147483647>
minstd_rand0;
```
• minstd_rand: Linear congruential generator
• ```typedef linear_congruential<unsigned long, 48271, 0,
2147483647>
minstd_rand;
```
• mt19937: Marsenne twister
• ```typedef mersenne_twister<unsigned long, 32, 624, 397, 31,
0x9908b0df,
11, 7, 0x9d2c5680, 15, 0xefc60000, 18> mt19937;
```
• ranlux_base_01: Generator based on subtraction with carry
• ranlux3 si ranlux4: Discarding generator based on subtraction with carry
• ```typedef subtract_with_carry<unsigned long, 1 << 24,
10, 24> _Ranbase;
```
• ranlux3_01 si ranlux4_01: Discarding generator based on subtraction with carry
• ```typedef subtract_with_carry_01<float, 24, 10, 24>
_Ranbase_01;
```
• ranlux_64_01: Generator based on subtraction with carry
• ```typedef subtract_with_carry_01<double, 48, 5, 12>
ranlux64_base_01;
```

### Distributions

In TR1 terms, a distribution is a class that transforms a stream of uniformly distributed random numbers (generated by an engine) into a stream of numbers in a particular distribution. The random numbers produced by an engine are always uniformly distributed. To change the distribution of these numbers, you have to use a distribution class.

All distribution classes have the following methods:

• reset(): Clears all cached values that were previously generated by an engine
• operator(): Returns values (one at a time) within a specific distribution (numbers generated by an engine)

TR1 provides the following distribution classes:

### How to Use Engines and Distributions

The simplest way to generate random numbers is to use a generator. The following example uses a linear congruential generator to generate 10 numbers, uniformly distributed.

```// linear congruential generator
std::tr1::minstd_rand gen;

// initialize the generator
gen.seed((unsigned int)time(NULL));

// generate the numbers
for(int i = 0; i < 10; ++i)
{
std::cout << gen() << " ";
}
std::cout << std::endl;
```

If the seeding is forgotten, the same sequence is generated each time you run the program:

```48271 182605794 1291394886 1914720637 2078669041 407355683
1105902161 854716505 564586691 1596680831
```

If you wanted to generate numbers in the interval [0, 9], you can apply the modulo 10 function on the generated numbers.

```for(int i = 0; i < 10; ++i)
{
std::cout << gen() % 10 << " ";
}
```

The same result, 10 numbers uniformly distributed between 0 and 9, can be generated by combining the generator with a uniform distribution.

```// linear congrunetial generator
std::tr1::minstd_rand gen;

// uniform integer distribution
std::tr1::uniform_int<int> dist(0, 9);

// initialize the generator
gen.seed((unsigned int)time(NULL));

// generate the numbers
for(int i = 0; i < 10; ++i)
{
std::cout << dist(gen) << " ";
}
std::cout << std::endl;
```

Another possibility is to associate a generator with a distribution using the variate_generator class.

```// linear congrunetial generator
std::tr1::minstd_rand gen;

// uniform integer distribution
std::tr1::uniform_int<int> dist(0, 9);

// initialize the generator
gen.seed((unsigned int)time(NULL));

// associate a generator with a distribution
std::tr1::variate_generator<
std::tr1::minstd_rand,
std::tr1::uniform_int<int>> combgen(gen, dist);

// generate numbers
for(int i = 0; i < 10; ++i)
{
std::cout << combgen() << " ";
}
std::cout << std::endl;
```

If seeding had been done after defining combgen, the sequence would have been the same with each run.

```// associate a generator with a distribution
std::tr1::variate_generator<
std::tr1::minstd_rand,
std::tr1::uniform_int<int>> combgen(gen, dist);

// initialize the generator
gen.seed((unsigned int)time(NULL));
```
```0 6 8 9 1 5 3 2 7 0
```

The reason for this is that a copy of the (uninitialized) generator is made when instantiating combgen. If the type of the generator was a reference type, initialization could have been done after.

```// associate a generator with a distribution
std::tr1::variate_generator<
std::tr1::minstd_rand&,
std::tr1::uniform_int<int>> combgen(gen, dist);

// initialize the generator
gen.seed((unsigned int)time(NULL));
```

The same thing happens if you use a pointer type:

```// associate a generator with a distribution
std::tr1::variate_generator<
std::tr1::minstd_rand*,
std::tr1::uniform_int<int>> combgen(&gen, dist);

// initialize the generator
gen.seed((unsigned int)time(NULL));
```

The next sample shows how to use a combined generator. This generator is initialized not with a value, but with a random number produced by another generator.

```// engines
std::tr1::minstd_rand gen1;
std::tr1::mt19937 gen2;
std::tr1::linear_congruential<unsigned long, 33614, 0,
2147483647> seeder;

// initialize the seeder
seeder.seed((unsigned int)time(NULL));

// combined engine
std::tr1::xor_combine<
std::tr1::minstd_rand,    // first engine
// shifting value for the numbers from the first engine
7,
std::tr1::mt19937,        // second engine
// shifting value for the numbers from the second engine
13
> xorgen(gen1, gen2);

// exponential distribution
std::tr1::exponential_distribution<float> expdist(2);

// initialize the combined generator
xorgen.seed(seeder);

// generate numbers
for(int i = 0; i < 10; ++i)
{
std::cout << xorgen() << " ";
}
std::cout << std::endl;
```

#### Conclusions

With TR1, the standard C++ library becomes richer in the possibilities of generating random number generators. Engines and distributions can be combined to generate numbers to meet various requirements. Perhaps, in the future, MSDN also will be enriched with examples for their usage. In the meantime, hopefully this article provides a good introduction for that.

#### Marius Bancila

Marius Bancila is a Microsoft MVP for VC++. He works as a software developer for a Norwegian-based company. He is mainly focused on building desktop applications with MFC and VC#. He keeps a blog at www.mariusbancila.ro/blog, focused on Windows programming. He is the co-founder of codexpert.ro, a community for Romanian C++/VC++ programmers.

• #### beauty from clarisonic venerable

Posted by iouwanzi on 06/06/2013 05:22am

• #### GHD skÃ¸nhed poster tendens til at vÃ¦re for at kunne lÃ¥se prÃ¦cis hvad en stor designer er faktisk for dit tÃ¸j

Posted by motherdhmm on 05/30/2013 01:00pm

[url=http://www.buy-beatsdrdre.com/]beats by dre headphones[/url] PÃ¥ nuvÃ¦rende tidspunkt i Danmark, ghd fladjern stigende salg boom, men ogsÃ¥ fremkomsten af ??en rÃ¦kke websteder, der sÃ¦lger ghd glattejern der er en Ã¦gte ghd hÃ¥ret identifikation, og vi ghd glattejern online markedsfÃ¸ring, GHD glattejern klassificering klare design. SÃ¸g nemt og hurtigt, autentiske ghd hÃ¥ret overkommelig design-orienteret Ã¸verste hÃ¥ndtag design og et unikt serienummer til internt brug. Kan ses med de standard funktioner ghd glattejern, frem for alt, sÃ¥ du vÃ¦rd investeringen. [url=http://www.blog.cheapbeatsbydre.co.nz/beats-by-dre-headphones]beats by dre headphones[/url] Absolut forskning den faktiske visse udstyret interiÃ¸r, at vÃ¦lge et tage et kig pÃ¥ hÃ¸jre ind GHD merchandise siden den ideelle Ã¦gtefÃ¦lle Hvis du overvejer blot om enhver type, der er tilknyttet barnet inden for sÃ¦tninger involverer. GHD er definitivt nÃ¦sten helt sikkert de sÃ¦rlige producerede leverandÃ¸rer, som vil prÃ¦sentere korrekt vÃ¦rdige af tresses straightners med hinanden og hÃ¥rtÃ¸rrer. [url=http://www.blog.cheapbeatsbydre.co.nz/monster-headphone]monster beats headphone[/url] HÃ¥r er en kvindes identitet, Enhver kvinde hÃ¥ber alle, at gennem de forskellige stilarter til at Ã¦ndre billedet, Face, at gÃ¸re sig smukkere, mere ungdommeligt, eller elegance, vil man vÃ¦re i stand til at opfylde alles idÃ© om hÃ¥r, Vi lÃ¦rer sammen, hvordan til at vÃ¦lge billige ghd glattejern? ghd glattejern, hvordan du bruger? Forberedelse.

• #### Lightweight perceptive â Nike Unshackled TR Right in shoot up 2013 3 series

Posted by Tufffruntee on 04/22/2013 03:47am

Nike Free TR Fit 3 unmistakable features is to exploit the new scheme: Nike Self-ruling 5 soles improved bending Striation; modern tractor imitate making training more focused when; lighter load, the permeability is stronger, and more smart shoe designs not only order shoes [url=http://northernroofing.co.uk/roofins.cfm]nike free run 3[/url] more comfortable wearing, barefoot training caress, but also more in fashion appearance. Nike Relieve TR Robust 3 provides excellent lateral perseverance, you can be suffering with the legs in the part during training. Diligent vamp majuscule letters breathable mesh, lower suds's one of a kind delineate can be [url=http://markwarren.org.uk/property-waet.cfm]air max 90 uk[/url] seen under the aegis it. Lightweight, ragged, thin foam material occupied past completely occasional seams, more limber, support is stronger. Lack more advance, factor of a training irritate, froth neck in more parts of the neediness in return give, bubble loose. Put to use twice say nothing moisture wicking fake materials, flat on your feet, help maintenance feet sear and comfortable. Phylite [url=http://northernroofing.co.uk/roofins.cfm]nike free run[/url] midsole offers lightweight shock unchanging, superior durability and stable outsole can do to greatly lower the total weight of the shoe. Qianzhang pods on the outsole and heel-shaped Grassland rubber enhances the shoe multi-directional drag on odd surfaces.

• #### Women's clothing from Distance features the latest styles and fashions that you are unblinking to melodic tooth

Posted by carpitojx on 04/16/2013 01:23am

We wanted to choose some in days of yore to highlight some of the talented shops [url=http://www.hollistercorfrance.fr]hollister france[/url] revealed there that coordinate supported CONFORM TO as a replacement after so long and are doing engaging things in their parts of the hinterlands or the enchantä¿¥ ' [url=http://www.abercrombiesfrancevparise.fr]abercrombie france[/url]. There are renowned maverick retailers into public observe there, innumerable of which are cultivating trends in the forefront they trounce the larger market. It's so rush to go to our ticket and our retailers to [url=http://www.airjordanfrpaschere.fr]jordan[/url] constantly be evolving. We all include so much taste representing the assiduity we lucubrate away in and the reciprocal target of pushing the sedulousness forward. Sufficiency jibba jabba, today's article is on MUST STOCK CO in Richmond, [url=http://www.abercrombieufrancersoldes.fr]abercrombie[/url] VA. The Nakate Bash also works to generate artisans in country areas [url=http://www.airjordanspasuchere.fr]air jordan[/url] of Uganda that we appreciate as occasion finished untapped or undervalued. They resist in providing income into women that are struggling to put championing themselves [url=http://www.hollisterfrancevmagesin.fr]hollister[/url] and, with a view the duration of bounteous of them, the families that are relying on their income. The predict also adheres to objective barter principles and environmentally friendly practices [url=http://www.abercrombievandfitchuks.co.uk]abercrombie[/url] including maximizing the pour down the drain of sore materials from sustainably managed sources, buying locally where practicable and encouraging our artisans to succeed in environments of their choosing â which are all together after tempo in the disclose [url=http://www.monclerfrancermagasinsfr.fr]moncler[/url] air. But in November, we each had a dialect mayhap to control a step assist and look [url=http://www.airjordanzchaussuren.com]air jordan[/url] at things from a far apart from perspective. We had been in so abstruse, plugging away, racing on to the next gismo that we hadnât bewitched the plan to look up [url=http://www.michaelukorsua.com]michael kors outlet[/url] and summon inquire ourselves what we definitely wanted.Weâve dedicated two and a half years to creating a brand and a commodity that exceeded our (wildest) expectations. Weâve lettered more than we at all times soupån [url=http://www.hollisterucoboutiquer.fr]hollister[/url] possible. Weâve met awe-inspiring people and made expensive connections. Weâve discovered a passion championing something we didnât withdraw we had.But with all of this advance, weâve recently realized that revolvement threads [url=http://patrimoine.agglo-troyes.fr/BAM/louboutinpascher.html]louboutin pas cher[/url] is no longer something we desire after, or sensation we pressure, to proceed with what we were meant to do.

• #### What is TR1?

Posted by inbugable on 07/11/2008 11:59pm

Please mention what TR1 is, and how to get it.

• #### Re: What is TR1

Posted by cilu on 07/28/2008 06:10am

I explain what this is in the first article of the series. TR1 stands for Technical Report 1, which specifies the new additions to the C++ standard. Microsoft provides an early implementation for these new things and they are available with the Visual C++ Feature Pack (http://www.microsoft.com/downloads/details.aspx?FamilyId=D466226B-8DAB-445F-A7B4-448B326C48E7&displaylang=en).

• You must have javascript enabled in order to post comments.

## Top White Papers and Webcasts

• When individual departments procure cloud service for their own use, they usually don't consider the hazardous organization-wide implications. Read this paper to learn best practices for setting up an internal, IT-based cloud brokerage function that service the entire organization. Find out how this approach enables you to retain top-down visibility and control of network security and manage the impact of cloud traffic on your WAN.

• U.S. companies are desperately trying to recruit and hire skilled software engineers and developers, but there is simply not enough quality talent to go around. Tiempo Development is a nearshore software development company. Our headquarters are in AZ, but we are a pioneer and leader in outsourcing to Mexico, based on our three software development centers there. We have a proven process and we are experts at providing our customers with powerful solutions. We transform ideas into reality.