# Generate a range of number with X being returned most of the time

I am attempting to write a RNG which returns a normal-like curve. For example, say I define X to be 4, I would like to generate a range of numbers from 1 to 8, but with 4 being returned most of the time (say 60%).

How can I accomplish this in a way I can easily define X, and the range of the numbers?

You can easily generate numbers from range <0,1> with uniform distribution and then project them to range <0,2X> with function like in the graph:

http://filmy.zaachi.com/up_images/full/graph.png

It's up to you to choose function (it can be for example some trigonometric function or some more sofisticated function which generates normal distribution - like Gaussian function).

If you have generator with normal distribution, just just multiply generated number with 2X.

• Tip: Use the ziggurat algorithm for that, unless the distribution you're looking for has more efficient algorithms available (like Cauchy-Lorentz) and you don't mind having multiple variants of the code. Even then, Ziggurat is still a fast alternative. Good overview: "Computer Generation of Statistical Distributions" (2000) by Richard Saucier, US Army Research Laboratory. Commented Sep 16, 2011 at 9:56

You can also use the 'ol dice which is a crude way to 'boost' the middle numbers.

1 dice = 1..6 (equal distribution) 2 dices = 2..12 with 7 having a probability of 1/6 (6/36) and 2 a probability of 1/36.

You could also try something like this to simulate that functionnality with any numbers:

int getrandom(int start, int stop)
{
int a=stop-start+1;
int r = (rand(a) + rand (a)) / 2;
return(r + start);
}


where rand(x) is supposed to return a number from 0 to x-1 (ie rand(5) gives 0 to 4)

You can add the probability for those middle numbers by adding the rand (a) several times ie. :

int r = (rand(a) + rand (a)+ rand (a)) / 3;


or

int steepness=7;
r=0;
for(int i=0;i<steepness;i++;
r+=rand(a);
r/=steepness;


Talking about percentage, you can generate an integer number from 0 to 99 than subdivide your 100% into chunks of different sizes:

| 10 | 10 |   20    |      30      |      30      |
1    5      2            4             3


so if random is [0 10[ => 1; [10 20[ => 5; [20 40[ => 2 [40 70[ => 4 [70 100[ =>5

this means that you will get 1 and 5 with 10%, 2 with 20%, 3 and 4 with 30%.

This method can be stressed further as @zacharmarz correctly pointed out.

Whichever size you use for your uniform generation, you will arrive to run out resolution so you know that will be points in the curve that you will never reach. Let say that MAXRAND is 1000, you can't newer get results of the curve beween 123 and 124 for example. You can go further by doing another generation so you can subdivide the curve between 123 and 124 in 1000 pieces

here an example with MAXRAND = 6 (!!)

The orange comes from the first extraction and the dark cyan comes from the second one