<--- Return to Excel Statistics Guide
Normally Distributed Random Numbers in C++
Keith Greiner
August 8, 2020
This essay is about how to create a normally distributed random number in C++. The example program will create a collection of 10,000,000 normally distributed random numbers, and will tabulate the numbers to demonstrate that they are, in fact, normally distributed. Three sections follow:
1. Normally distributed random numbers from the inverse of the cumulative density function, normal distribution function.
2. Nearly normally distributed random numbers from the average of ten other random numbers.
3. Comparison of the two methods.
1. Inverse of Cumulative Density Function
The first method uses the inverse of the cumulative density function. There are a number of ways to obtain the inverse, and this example returns the most accurate value that I have found. A number of functions that are available on the internet do notreturn a correct value, but this one is different: it is correct. The collection of functions was published by John Burkhardt at: https://people.sc.fsu.edu/~jburkardt/ . You will need to download his two asa241 files. When you connect to the site, click on C++ programs and then on ASA241. I copied the contents of file asa241.cpp and saved the contents to a file I named “asa241_support_functions.h”.I then copied the contents of file asa241.hpp and saved it to a file named “asa241.h”. Both files were added to the C++ project.
Code for the C++ program may be found in a .txt file at this address. I suggest you copy contents of the .txt file and paste those contents into a C++ program created in your editor. When I ran it, everything worked, and the program ran the first time. I cannot guaranty that your experience will be the same. If you try to run the program in Visual Studio, you will need to make changes to accommodate the peculiarities of VS. Otherwise, the problem will be an opportunity to develop your problem-solving skills.
Carefully read and understand the comments that are shown in the .txt file and the asa241 files.
The example is set up to use the function “r8_normal_01_cdf_inverse ( Random_Number );” from the asa241 collection. When you provide this function with a random number between 0 and 1, it will return a normally distributed random number. Multiple calls to the f8... function will have a mean of zero and a standard deviation of 1.
If you want to try the method of averaging, that is described below, just remove the two comment indicators “//” from the line “//Random_Number_Normal_Dist = Normally_Distributed_Random_Number_from_Average(11);”
Since this redefines the value of Random_Number_Normal_Dist, you could just leave the call to the “f8…” function.
2. Average of Random Numbers
When a series of random numbers is averaged, the result will be nearly normally distributed. I say that it is “nearly normally distributed” because the random process can result in a variety of distributions with slightly different shapes. The example program draws ten random numbers and then calculates an average of the ten. The average is then tabulated.
If the “Range_of_Values” variable is 11, and the number of averaged numbers is 10, then the returned value will have a mean of zero and a standard deviation of 1. Other settings will result in distributions having other means and standard deviations, but that are reducible to a standard normal distribution form.
Look for the function named “double “Normally_Distributed_Random_Number_from_Average(double Range_of_Values)” that is located prior to main()
3. Comparison of the Two Methods
While the f8… function is seen as the precise way to create a normally distributed random number, the average of 10 random numbers is a close simulation. Below is a table that shows the bin numbers of 100 bins, the categories of output values for each bin, and three columns of tabulations of output from the program.
Below is a graphical comparison of the distribution from the f8... function and one of the averages. Notice how the distribution from the averages is slightly lower at the peak, and slightly narrower at the tails.