Random numbers are one of the most important parts of today’s modern programming technologies. They are used in mathematics, physics, in many engineering fields, and in programming such as generating random data for testing, random maps in levels, random trees on a planet – the list is endless. Since C++11, mt19937 (`std::mt19937`

) is implemented as a random number generator. In this post, we explain what **mt19937** is and how we can use it.

Table of Contents

## What is a random number and a random number generator in C++?

**A random number** is a number that is randomly chosen in a given range. It is impossible to predict future values based on past or present values and they are uniformly distributed over a defined interval or set.

**Mersenne prime** is a prime number used in mathematics that is a number of the form *Mn* = 2*n* − 1 where the n is an integer. The **Mersenne Twister** is a pseudorandom number generator where the period length is chosen to be a Mersenne Prime. It was developed by Makoto Matsumoto in 1997.

Since C++11, the Mersenne Twister mathematical number generator is implemented as a random generator number, it is defined in the `<random>`

header as a `std::mersenne_twister_engine`

that is a random number engine based on* Mersenne Twister* algorithm.

## What is the std::mt19937 random number generator in modern C++?

In C we use `rand()`

, `srand()`

and in C++ we use `std::rand()`

, `std::srand()`

. While they are added to `<cstdlib>`

to make modern C++ compatible, there are more useful and modern random number generators. These are `std::mt19937`

and `std::mt19937_64`

. The `std::mt1993`

is a 32-bit Mersenne Twister by Matsumoto and Nishimura in 1998, and `std::mt19937_64`

is a 64-bit Mersenne Twister by Matsumoto and Nishimura in 2000.

The `std::mt19937`

is a random number generator defined in the `<random>`

header in C++17 standard and beyond, producing 32-bit pseudo-random numbers by using **the M**ersenne **T**wister algorithm with a state size of **19937** bits. This is why it is called **mt19937** and there is a 64-bit version called **mt19937_64**. Both are defined as an instantiation of the mersenne_twister_engine. Now let’s see their definitions.

Since C++11, **mt19937** is defined as below,

1 2 3 4 5 6 7 8 |
typedef mersenne_twister_engine<unsigned int, 32, 624, 397, 31, 0x9908b0df, 11, 0xffffffff, 7, 0x9d2c5680, 15, 0xefc60000, 18, 1812433253> mt19937; |

Since C++11, **mt19937_64** is defined as below,

1 2 3 4 5 6 7 8 |
typedef mersenne_twister_engine<_ULonglong, 64, 312, 156, 31, 0xb5026f5aa96619e9ULL, 29, 0x5555555555555555ULL, 17, 0x71d67fffeda60000ULL, 37, 0xfff7eee000000000ULL, 43, 6364136223846793005ULL> mt19937_64; |

## How can we use the random number generator std::mt19937 in modern C++?

Simply we can generate modern random number as shown below.

1 2 3 |
std::mt19937 rnd( std::time(nullptr) ); |

we can use it like so:

1 2 3 |
unsigned int r = rnd(); |

if you want to generate a number in a range you can use modulus operator %.

This is how can we generate random number between zero to n, i.e. 0 to 100.

1 2 3 |
unsigned int r = rnd()%100; |

This is how can we generate random number between two numbers, i.e. 50 to 150,

1 2 3 |
unsigned int r = 50 + rnd()%100; |

## Is there a simple example to use std::mt19937 in modern C++?

Here is a simple example to use `std::mt19937`

.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <iostream> #include <random> #include <ctime> int main() { std::mt19937 rnd( std::time(nullptr) ); std::cout << "32bit Random MT Number:" << rnd() << std::endl; system("pause"); return 0; } |

## Is there a full example of how to use the std::mt19937 in modern C++?

The `std::mt19937`

and `std::mt19937_64`

can be initialized with a new seed values (as same as using `std::srand()`

) with the `seed()`

method. Thus, we can generate same random number in same processes. This is useful to generate same randomly generated numbers for the same processes, such as it can be used to generate maps for each level of a game. We can also check `min()`

and `max()`

values of this generator.

Here is a full example including all these above.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#include <iostream> #include <random> #include <ctime> #include <cstdlib> int main() { std::srand(std::time(nullptr)); auto r = std::rand(); std::cout << "C Style Random Number:" << r << std::endl; std::cout << std::endl; std::mt19937 rnd( std::time(nullptr) ); std::cout << "32bit Random MT Number:" << rnd() << std::endl; std::cout << "32bit Random MT Number:" << rnd() << std::endl; std::cout << "Random MT Number (0-100):" << rnd()%100 << std::endl; std::cout << "Random MT Number (50-150):" << 50+rnd()%100 << std::endl; std::cout << std::endl; std::cout << "32bit Min MT Number:" << rnd.min() << std::endl; std::cout << "32bit Max MT Number:" << rnd.max() << std::endl; std::cout << std::endl; // Initializing a new random sequence with a seed value rnd.seed(4194967295); std::cout << "32bit Random MT Number:" << rnd() << std::endl; std::cout << "32bit Random MT Number:" << rnd() << std::endl; std::cout << std::endl; // Initializing same random sequence with a seed value rnd.seed(4194967295); std::cout << "32bit Random MT Number:" << rnd() << std::endl; std::cout << "32bit Random MT Number:" << rnd() << std::endl; std::cout << std::endl; system("pause"); return 0; } |

The output will be as below.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
C Style Random Number:16170 32bit Random MT Number:3102484612 32bit Random MT Number:2117116903 Random MT Number (0-100):28 Random MT Number (50-150):93 32bit Min MT Number:0 32bit Max MT Number:4294967295 32bit Random MT Number:88738114 32bit Random MT Number:32125358 32bit Random MT Number:88738114 32bit Random MT Number:32125358 Press any key to continue . . . |

As you see, we can use seed to generate same random number sequences as in the last 4 lines of the output above.

Here are more examples to generate random numbers in modern C++,

I should note that, personally, I found `mt19937`

name for this class is hard to remember, I would prefer `rand32()`

, `rand64()`

names for them.

For more details about this feature in C++11 standard, please see these papers; p0205r1

**C++ Builder is the easiest and fastest C and C++ compiler and IDE for building simple or professional applications on the Windows operating system. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for UIs.**

**There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise versions of C++ Builder and there is a trial version you can download from here.**