Math.random(num = 1)

Why not allowing an argument to Math.random() so that instead of having to do 10000 * Math.random() we can simply do Math.random(10000)?

Saving one character is a pretty small benefit to adding complexity to an API.

1 Like

Given how widely confusing it is for most JS developers to use Math.random, especially juniors, my general sentiment would be to support for this, but I could see this becoming a slippery slope very quickly.

What if you want to offset the start and end value and how many decimal points you want to include. Next thing you know, you're using this syntax…

Math.random = function(max = 1, min = 0, precision = Infinity) {
  // function logic here...
}

…and everybody is more confused than they were using Math.random in its current implementation.

As much as I'd love to see this function made simpler to use, it's hard to imagine a use case that's simpler for all use cases than what's already in place. Instead, I'd opt for a helper function you can expose globally in your codebase, like this:

function getRandomInt(a = 1, b) {
  const [min, max] = (b === undefined ? [0, a] : [a, b]).sort((a, b) => a - b);
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

This covers several use cases:

  • No args: By default, this helper function returns a boolean-ish number (1 (truthy) or 0 (falsy)), which could be considered a feature in itself. This way, you could do something like Boolean(getRandomInt()) to get a random boolean, or maybe even wrap that in another helper function like getRandomBool.

    Example: getRandomInt() // 0 | 1
    Example: Boolean(getRandomInt()) // true | false

  • 1 arg: With a single arg, that arg stands as the max when positive or min when negative, with the opposite value (min or max) defaulting to 0.

    Example: getRandomInt(10) // 0-10, inclusive

  • 2 args: When using both args, the args represent both the min and max values and auto-sort numerically in case the min is higher than the max.

    Example: getRandomInt(5, 10) // 5-10, inclusive

getRandomBool could look like this:

function getRandomBool() {
  return Boolean(getRandomInt());
}

What I'd really like to see is a more full-fledged random API for JavaScript. So, you'd have functions like randomInt(start, end), randomFloat(start, end), randomBoolean(), maybe you can even have different randomFloat() functions that generate numbers over configurable distributions. The ability to seed multiple independent generators would be nice as well.

I had started a bit of a discussion around this in the past: A more complete random API?

5 Likes

I think it would be more conventional, something like this

Number.random(start: number = 0, end: number = 1.0)   ->   number
BigInt.random(start: bigint = 0n, end: bigint = 4294967295n)   ->   bigint
String.random(start: string = "A", end: string = "z")   ->   bigint
2 Likes

It's probably not a good idea to modify the Math.random() signature.

Any existing code containing statement as Math.random() parameter will change behavior.

This is sometime used to minify code, example:

foo();x=Math.random()
x=Math.random(foo()) // 1 char saved

Otherwise, you can use this minimal function that admit 0, 1 or 2 parameters:

const random = (min = 1, max = 0) => (max - min) * Math.random() + min

I hope automatic minifiers aren't doing this. Maybe code-golfers are.

I've heard it said around that adding new parameters to existing functions is not considered a breaking change, unless there's evidence of actual websites doing it. And, indeed, we often see proposals updating function signatures of existing functions to support new parameters.

1 Like

I have a javascript utility file that grows slowly everytime i work with javascript and implementing various forms of randomness is something i've found myself doing. i found it much better to make a custom random function

function random () : Number;

random.int (max : Number) : Number;
random.int (min : Number, max : Number) : Number;

random.choose (array : Array) : var;

random.weighted (weight : Number) : Number;

and so on...