jozenbasin
jozenbasin

Reputation: 2562

Random number generator rarely includes upper and lower bounds

I have some letters in an array, only 8 of them, starting at A and ending at H. Using a typical random number generator, I have found that A and H are very rarely generated. How can I make this more inclusive for these two bounds?

var allowedLetters = ["A","B","C","D","E","F","G","H"];
var i = Math.round(Math.random() * (allowedLetters.length - 1));
var letter = allowedLetters[i];
    
console.log(letter)

Upvotes: 1

Views: 487

Answers (3)

smnbbrv
smnbbrv

Reputation: 24581

var allowedLetters = ["A","B","C","D","E","F","G","H"];
var calledTimes = [0,0,0,0,0,0,0,0];
var i = 0;

while (i++ < 100000) calledTimes[Math.round(Math.random() * (allowedLetters.length - 1))]++;

console.log(calledTimes);

This happens because of Math.round specifics. Use Math.floor instead:

var allowedLetters = ["A","B","C","D","E","F","G","H"];
var calledTimes = [0,0,0,0,0,0,0,0];
var i = 0;

while (i++ < 100000) calledTimes[Math.floor(Math.random() * allowedLetters.length)]++;

console.log(calledTimes);

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386756

round is is wrong, because only half of the slot of the random values goes to the lower index and half of the slot goes to the upper index.

var values = ["A", "B", "C", "D", "E", "F", "G", "H"],
    index,
    count = {},
    i = 1e6;

while (i--) {
    index = Math.round(Math.random() * (values.length - 1));
    count[values[index]] = (count[values[index]] || 0) + 1;
}

console.log(count);

You could use Math.floor with the full length of the array as factor.

var values = ["A", "B", "C", "D", "E", "F", "G", "H"],
    index,
    count = {},
    i = 1e6;

while (i--) {
    index = Math.floor(Math.random() * values.length);
    count[values[index]] = (count[values[index]] || 0) + 1;
}

console.log(count);

Upvotes: 1

Jonas Wilms
Jonas Wilms

Reputation: 138477

 var i = Math.round(Math.random() * (allowedLetters.length - 1));

Cause the first and the last element got a range of 0.5, all the others got 1. Might do this instead:

var i = Math.floor(Math.random() * allowedLetters.length);

Were all elements get the same distribution.

Upvotes: 2

Related Questions