Quick Math.random question

Hi,

If I want to return a number between 1.2 and 0.8 isnt this correct?
`Math.random() * (1.2 - 0.8) + 0.8` ?

Hi there ReGGaeBOSS,

it looks all right to me.

Though you may want to use thisâ€¦

``(Math.random()*(1.2-0.8)+0.8).toFixed(1);``

1 Like

thx!=)

that gives a string rather than a number though.

Hi there ReGGaeBOSS,

as Stephen has rightly pointed outâ€¦

If a string does not meet your requirement, then use thisâ€¦

``` Math.round((Math.random()*(1.2-0.8)+0.8)*10)/10;```

Although I donâ€™t think using Math.round will give a uniform distribution. Only [8. 8.5) will be rounded to 8, whereas [8.5, 9.5) will be rounded to 9. Using Math.floor may be a better bet.

Hi there r51,

correct me if I am wrong, and I very often am , butâ€¦

``Math.floor((Math.random()*(1.2-0.8)+0.8)*10)/10;``

â€¦does not appear to give the upper limit.

Thatâ€™s right. Math.random() < 1. But Math.round isnâ€™t the way to fix that problem because the numbers at both extremes of the range you want will turn up half as often as the others.

Hereâ€™s a quick test of floor vs round. round gave me halved frequencies as expected.

``````function integerBetween (lower, upper, inclusiveUpper) {
var inclusiveAdjustment = inclusiveUpper ? 1 : 0;
var range = upper - lower + inclusiveAdjustment;
return Math.floor(Math.random() * range) + lower;
}

function integerBetweenRound(lower, upper) {
return Math.round(Math.random() * (upper - lower) + lower);
}

var i;
var integer;

for (i = 0; i < 10000; i++) {
integer = integerBetween(8, 12, true);
}

for (i = 0; i < 10000; i++) {
integer = integerBetweenRound(8, 12);
}

``````

It should be

``````Math.floor((Math.random()*(1.3-0.8)+0.8)*10)/10;
``````

Math.random returns a value where** 0 <= value < 1 ** so if you multiply that by a number you get values between zero (inclusive) and just less than the number you multiplied by. So if you use Math.floor you get between zero and one less than what you multiplied by.

Since you want one decimal place you will want 0.1 greater in order for all the possible results to be equally likely.

Using round would split one values share between zero and the maximum number with zero being very very slightly more probable since zero itself is included.

Perhaps it will be easier if you create a function:

``````function random(min, max, dec) {
var multiplier = Math.pow(10, dec);
max *= multiplier;
min *= multiplier;
return Math.floor(Math.random()*(max-min+1)+min)/multiplier;
}

console.log(random(0.8,1.2,1));
``````

where the parameters are - minimum value, maximum value and number of decimal places in result

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.