Random numbers are used frequently in programming. Random numbers are especially important in game development, visual art, and website animation, where they serve many different purposes. In programming, the term random number often brings to mind “uniform random numbers,” where all values appear with the same frequency.
In many cases, random numbers generated from a uniform distribution are sufficient. In some situations, however, using biased random numbers instead of uniform random numbers can make the appearance of content or the behavior of a phenomenon feel more natural.
By adding one extra operation to a uniform random number, it is possible to control bias in the random-number distribution. This article introduces several patterns for generating random numbers with the distribution you want.
Random-number distribution simulation demo
The following demo calculates the frequency of generated random numbers in real time and visualizes the results in a graph. Select a random-number type from the drop-down menu at the bottom of the screen to display the frequency distribution for that method.

Note: The demo is implemented with the Canvas API and ES Modules.
The sections below introduce the formulas, tendencies, and typical use cases for each type of random number.
Standard random numbers: uniform random numbers

// Standard random number
const value = Math.random();
These are called uniform random numbers: values from 0.0 to 1.0 appear evenly. In JavaScript, this is provided as the Math.random() function. In most programming languages, the only random-number function available by default is a uniform random-number function. This is probably the type of random number you use most often.
Adding random numbers: bias toward the center

// Adding random numbers
const value = (Math.random() + Math.random()) / 2;
This method generates two random numbers and adds them together. The distribution becomes linear, and values near the center appear more frequently.
Multiplying random numbers: increasing the proportion near zero

// Multiplying random numbers
const value = Math.random() * Math.random();
This method generates two random numbers and multiplies them. Values near 0.0 appear more frequently. Because the frequency decreases as the value increases, this method is useful when you want to add a natural bias.
Squaring a random number: increasing the proportion near zero even more

// Squaring a random number
const r = Math.random();
const value = r * r;
This method squares a random number. Values near 0.0 become exceptionally frequent, producing a steeper distribution than the multiplication method. Another characteristic is that values greater than 0.1 become much less likely to appear. Use this method when you want a clear bias. By combining random numbers in this way, you can obtain a variety of distributions.
Square root of a random number

// Square root of a random number
const value = Math.sqrt(Math.random());
This method takes the square root of a random number. The frequency increases linearly from 0.0 to 1.0.
Normally distributed random numbers

function calcNormalRandom() {
while (true) {
const r1 = Math.random();
const r2 = Math.random();
// Generate a normally distributed value with the Box-Muller transform
const normal =
Math.sqrt(-2.0 * Math.log(r1)) * Math.sin(2.0 * Math.PI * r2);
// Normalize the approximate -3 to +3 range to [0, 1)
const value = (normal + 3) / 6;
// Recalculate values outside [0, 1)
if (value >= 0 && value < 1) {
return value;
}
}
}
const value = calcNormalRandom();
console.log(value);
These random numbers follow a distribution called the normal distribution. It is widely used in statistics, and many types of statistical data, such as height and grades, follow this normal distribution. Values near the center appear most frequently, and the frequency drops sharply as values move away from the center, but any value can still occur. Because values can very rarely become unexpectedly extreme, practical use often sets upper and lower bounds and ignores values outside the desired range.
Inverting a distribution

// Multiplying random numbers
const valueA = Math.random() * Math.random();
// Invert the random number. Subtracting it from 1.0 flips the distribution horizontally.
const value = 1.0 - valueA;
Random numbers take values from 0.0 to 1.0, so subtracting a random number from 1.0 produces an inverted distribution. If you invert the multiplication method or the squared method, both of which produce a high frequency near 0.0, the frequency instead increases near 1.0.
Conclusion
Using different random-number distributions adds variety to random elements. In addition to the operations introduced in this article, you can generate many different random-number distributions by combining random numbers in other ways. Distribution control like this is often used on this site, including the ICS MEDIA homepage, for particle sizes, where smaller sizes are generated more frequently.
Although this article explains the logic in JavaScript, the same approach can be reused in other languages. Use random numbers with distributions that suit your specific purpose.

