I’ve found this standard normal random number generator in a number of places, one of which being from one of Paul Wilmott’s books. The idea is that we can use the Central Limit Theorem (CLT) to easily generate values distributed according to a standard normal distribution by using the sum of 12 uniform random variables and subtracting 6. In Excel, the implementation looks like this:
=RAND()+RAND()+RAND()+RAND()+RAND()+RAND()+RAND()+RAND()+RAND()+RAND()+RAND()+RAND()-6
By doing a simple cut-and-paste, we can stick this formula in an Excel cell and go on with our merry way assuming we have generated values from a standard normal distribution. But what is really going on here, and how good does this generator work?
The Idea
The idea behind this standard normal generator is simple and is based on the Central Limit Theorem. In a nut shell, if we define the following random variables.
Then we can approximate the distribution of using the CLT.
Since we know that the mean and variance of is
and
respectivly.
Finally, if we ‘standardize’ by subtracting the mean and dividing by its standard deviation we get a standard normal random variable.
So we have essentially taken the sum of uniform random variables and used them to approximate a standard normal random variable by applying the CLT. The important thing to keep in mind is that the more uniforms we use to do this, the better the approximation. You may be asking yourself why this looks nothing like the simple Excel formula I showed earlier. Well, something special happens when we use 12 uniforms; things start to simplify!
Voila! We have an easy to implement standard normal random number generator. We should still be a little concerned about the CLT approximation and we should probably ask ourselves if using only 12 uniform random variables is ‘good enough’.
Testing
Now to the fun part! I’ve written the following function which implements the above method in R.
## function that uses the CLT to generate standard normals from uniform ## n is the number of standard normal random numbers to generate ## m is the number of uniforms to generate for using the CLT CLT_normal <- function(n, m){ z <- rep(0,n) for(i in 1:n){ u <- runif(m,0,1) s <- sum(u) z[i] <- (s-m/2) / (m/12) } return(z) }
Using the generated values, we can perform a visual inspection using QQ normal plots for various values of m. I also generated results using m as 30 since 30 is often used as a rule-of-thumb for applying the CLT.
## test the normal generator using various values of m par(mfrow=c(2,2)) m <- 1 x <- CLT_normal(100000, m) qqnorm(x, main=paste("QQ normal m=", m)) qqline(x, col="red") m <- 6 x <- CLT_normal(100000, m) qqnorm(x, main=paste("QQ normal m=", m)) qqline(x, col="red") m <- 12 x <- CLT_normal(100000, m) qqnorm(x, main=paste("QQ normal m=", m)) qqline(x, col="red") m <- 30 x <- CLT_normal(100000, m) qqnorm(x, main=paste("QQ normal m=", m)) qqline(x, col="red")
Based on this output, the generated values have lighter tails than a normal distribution, but using 12 uniforms seems to be ok if one was performing a ‘quick and dirty’ analysis in Excel. 30 uniforms obviously performs better, but things start to slow down considerably and it would probably be better to write a function using the Box-Muller method if better accuracy in the tails was needed.

It is funny to check that the CLT applies in the medium values of the average of 12 uniforms but I would never advise to use this as a normal generator! Box-Mueller is both faster and accurate, even in the tails… There is thus no reason to recommend using this alternative!
I wouldn’t recommend it either, but I’ve seen it used in Excel as a quick-and-dirty normal RNG. For those that don’t know Box-Muller (and there are a bunch of them in the corporate world) this would be their solution to a normal RNG. Accuracy in the tails is probably not their biggest concern!
If you’re using Excel anyway, wouldn’t it be a lot faster and easier just to use “=NORMSINV(RAND())”? That generates a perfect standard normal variate everytime. No fuss, no muss.
I wouldn’t say ‘perfect’. All normal inverse functions use some sort of approximation method. I know older versions of Excel had a NORMSINV() function whose approximation wasn’t very good.
This is simple as a conseption indeed.
Is it in applications? In the stats circles this mostly a toy example to introduce the generation of Normal variates. Yet, in finance this is no toy but a tool. They use it and they use it FOR REAL;)
Sad but true,huh?
Actually, there’s a very good reason to prefer this method to Box-Mueller. This method has bounded execution time. In theory Box-Mueller could loop forever randomly choosing points where -1<x<1 and -1<y 1.
*grumble*grumble*…stupid forum (at least *warn* me you can’t handle html symbols)
Box-Mueller can loop forever given it’s random x and y are:
x in [-1,1], y in [-1,1] where x*x + y*y exceeds 1
If you are using the ‘Rejection Method’ with the Box-Muller algorithm, you ‘accept’ a pair of normals about every 1.3 tries on average. So I think it is fairly efficient. On the other hand, if you have fast trig functions which give good estimates, there is no need to use the Rejection Method with Box-Muller.