27

I want to generate a random number between 1 and 10 up to 2 decimal places,

I'm currently using this below to generate my numbers,

var randomnum = Math.floor(Math.random() * (10.00 - 1.00 + 1.00)) + 1.00;

Ultimately, I would like to know how to generate numbers like:

1.66

5.86

8.34

In the format: var randomnum = then the code

sidenote: I don't remember why I previously had generated my numbers like that but remember something about Math.random generating numbers to 8 decimal places.

Thank you for the help! :)

Ps: I've seen a lot of posts about waiting to round down or up generated numbers and haven't found one wanting to generate them straight out.

UPDATE: I want a number value not a string that looks like a number

T.script
  • 297
  • 1
  • 3
  • 13
  • 1
    Numbers in JavaScript have the precision they have; it doesn't make a lot of sense to try and limit the precision to two decimal places. What you could do is generate *integers* between 1 and 1000 and then divide them by 100, but due to the nature of binary floating point you'll still end up with some "fuzz" in the fractional parts of the values. – Pointy Aug 17 '17 at 12:49
  • Possible duplicate of [Get a random number between 0.0200 and 0.120 (float numbers)](https://stackoverflow.com/questions/17726753/get-a-random-number-between-0-0200-and-0-120-float-numbers) –  Aug 17 '17 at 12:57
  • 1
    You can convert it using parseFloat.. What's the bog deal? –  Aug 17 '17 at 13:04
  • The link I provided has solution to create random decimal numbers which is your requirement. So you just have to convert the string using parseFloat(). That's all you have to do. –  Aug 17 '17 at 13:06
  • how would I do this? – T.script Aug 17 '17 at 13:08

7 Answers7

24

You were very close, what you need is not to work with decimal numbers as min and max. Let's have max = 1000 and min = 100, so after your Math.floor you will need to divide by 100:

var randomnum = Math.floor(Math.random() * (1000 - 100) + 100) / 100;

Or if you want to work with decimals:

var precision = 100; // 2 decimals
var randomnum = Math.floor(Math.random() * (10 * precision - 1 * precision) + 1 * precision) / (1*precision);
Observer
  • 3,506
  • 1
  • 16
  • 32
22

Multiply the original random number by 10^decimalPlaces, floor it, and then divide by 10^decimalPlaces. For instance:

floor(8.885729840652472 * 100) / 100  // 8.88

function genRand(min, max, decimalPlaces) {  
    var rand = Math.random()*(max-min) + min;
    var power = Math.pow(10, decimalPlaces);
    return Math.floor(rand*power) / power;
}

for (var i=0; i<20; i++) {
  document.write(genRand(0, 10, 2) + "<br>");
}

Edit in response to comments:
For an inclusive floating-point random function (using this answer):

function genRand(min, max, decimalPlaces) {  
    var rand = Math.random() < 0.5 ? ((1-Math.random()) * (max-min) + min) : (Math.random() * (max-min) + min);  // could be min or max or anything in between
    var power = Math.pow(10, decimalPlaces);
    return Math.floor(rand*power) / power;
}
tanguy_k
  • 11,307
  • 6
  • 54
  • 58
clabe45
  • 2,354
  • 16
  • 27
  • This is nice, but `genRand(2, 4, 1)` will never return 4.0. You'll need to add a modifier at the end depending on `max` (if max<4, mod=2.5e-16; if max<16, mod=1e-15, etc.). – thdoan Jul 29 '19 at 08:24
  • @thdoan Yes, the upper bound is exclusive. Can you elaborate on your way to make it inclusive? – clabe45 Jul 30 '19 at 01:17
  • clabe45, I was about to submit my own solution until I came across [this solution](https://snipplr.com/view/37687/random-number-float-generator/), so I'm going with it (why reinvent the wheel, right? :)). – thdoan Jul 31 '19 at 16:37
  • @thdoan Thanks, I don't know how that really differs from my solution though, because I don't think the `Math.min` is needed – clabe45 Aug 04 '19 at 21:23
  • clabe45, the difference is the one I linked to goes to 4.0 :). – thdoan Aug 05 '19 at 16:18
  • Ah I think the difference is that the one you posted formats the output as a string, rounding if necessary; rounding up, say, 3.96 to one decimal place will produce 4.0. I'm not sure if the distribution of that random function is even, though. I found [this](https://stackoverflow.com/a/9724775/3783155), and I'll update my answer. – clabe45 Aug 11 '19 at 03:09
  • It's easy enough to write a test case using a loop to gauge the distribution, say from -4.0 to 4.0. It was good enough for my usage. Thanks for the other solution though, always good to have multiple tools in our toolbox . – thdoan Aug 12 '19 at 06:23
  • @thdoan Ok, and no problem :-) – clabe45 Aug 13 '19 at 00:38
3

Just to simplify things visually, mathematically and functionally based on the examples above.

function randomNumberGenerator(min = 0, max = 1, fractionDigits = 0, inclusive = true) {
  const precision = Math.pow(10, Math.max(fractionDigits, 0));
  const scaledMax = max * precision;
  const scaledMin = min * precision;
  const offset = inclusive ? 1 : 0;
  const num = Math.floor(Math.random() * (scaledMax - scaledMin + offset)) + scaledMin;

  return num / precision;
};

The Math.max protects against negative decimal places from fractionDigits

Nickofthyme
  • 3,032
  • 23
  • 40
2

You can use below code.

var randomnum = (Math.random() * (10.00 - 1.00 + 1.00) + 1.00).toFixed(2);
Alien
  • 15,141
  • 6
  • 37
  • 57
vinay k hegde
  • 243
  • 4
  • 18
1

A more way with typescript/angular example:

getRandom(min: number, max: number) {
  return Math.random() * (max - min) + min;
}

console.log('inserting min and max values: ', this.getRandom(-10.0, -10.9).toPrecision(4));

getting random values between -10.0 and -10.9

Diego Venâncio
  • 5,698
  • 2
  • 49
  • 68
0

A simple javascript example to generate a random number with precision:

function genRand(min, max, decimalPlaces) {
    return (Math.random() * (max - min) + min).toFixed(decimalPlaces) * 1;
}

console.log(genRand(-5, 5, 2));
0

Here is another way not yet mentioned, which will generate a random number between 1 and 9.99...

(Math.random() * 8 + 1 + Math.random()).toFixed(2)

console.log((Math.random() * 8 + 1 + Math.random()).toFixed(2))

Whether this is the most practical approach is another question altogether.

oldboy
  • 5,729
  • 6
  • 38
  • 86
  • So this returns a string. You can check by using `typeof`. To make it work, wrap a parseFloat() around it so the output becomes a number. – RockyK Jan 17 '21 at 04:34