JS generate random boolean

JavascriptRandomBoolean

Javascript Problem Overview


Simple question, but I'm interested in the nuances here.

I'm generating random booleans using the following method I came up with myself:

const rand = Boolean(Math.round(Math.random()));

Whenever random() shows up, it seems there's always a pitfall - it's not truly random, it's compromised by something or other, etc. So, I'd like to know:

a) Is the above the best-practice way to do it?

b) Am I overthinking things?

c) Am I underthinking things?

d) Is there a better/faster/elegant-er way I don't know of?

(Also somewhat interested if B and C are mutually exclusive.)

Update

If it makes a difference, I'm using this for movement of an AI character.

Javascript Solutions


Solution 1 - Javascript

You can compare Math.random() to 0.5 directly, as the range of Math.random() is [0, 1) (this means 'in the range 0 to 1 including 0, but not 1'). You can divide the range into [0, 0.5) and [0.5, 1).

var random_boolean = Math.random() < 0.5;

// Example
console.log(Math.random() < 0.1); //10% probability of getting true
console.log(Math.random() < 0.4); //40% probability of getting true
console.log(Math.random() < 0.5); //50% probability of getting true
console.log(Math.random() < 0.8); //80% probability of getting true
console.log(Math.random() < 0.9); //90% probability of getting true

Solution 2 - Javascript

If your project has lodash then you can:

_.sample([true, false])

Alternatively you can use your own sample function (source):

const sample = arr => arr[Math.floor(Math.random() * arr.length)];

Solution 3 - Javascript

For a more cryptographically secure value, you can use crypto.getRandomValues in modern browsers.

Sample:

var randomBool = (function() {
  var a = new Uint8Array(1);
  return function() {
    crypto.getRandomValues(a);
    return a[0] > 127;
  };
})();

var trues = 0;
var falses = 0;
for (var i = 0; i < 255; i++) {
  if (randomBool()) {
    trues++;
  }
  else {
    falses++;
  }
}
document.body.innerText = 'true: ' + trues + ', false: ' + falses;

Note that the crypto object is a DOM API, so it's not available in Node, but there is a similar API for Node.

Solution 4 - Javascript

!Math.round(Math.random());

­­­­­­­­­­­­­­

Solution 5 - Javascript

Impressed a lot by Kelvin's answer I would like to suggest a fairly similar but slightly enhanced solution.

var randomBoolean = Math.random() < 0.5;

This solution is a bit more obvious to read, because the number on the right-hand side of < tells you the probability of getting true rather than of getting false, which is more natural to comprehend. Also < is one symbol shorter than >=;

Solution 6 - Javascript

Potentialy faster solutions...

Bitwise operator approach i just thought of Math.random() + .5 >> 0 or ~~(Math.random() + .5). Here is a performance test to judge for yourself.

let randomBoolean = Math.random() + .5 >> 0;                 //chance of true
const randomBoolean = chance => Math.random() + chance >> 0; //chance of true

The bitwise operators is in this case essentially just the same as using Math.trunc() or Math.floor(), therefore this is also posible Math.trunc(Math.random() + .5).

let randomBoolean = Math.trunc(Math.random() + .5);
const randomBoolean = chance => Math.trunc(Math.random() + chance);

Other more common solutions

The more common way to get random boolean is probably a comparative approach like Math.random() >= .5 from Kelvin's answer or Math.random() < .5; from Arthur Khazbs's answer, they actualy output true & false, and not 1 & 0.

let randomBoolean = Math.random() >= .5;                 //chance of false
const randomBoolean = chance => Math.random() >= chance; //chance of false

let randomBoolean = Math.random()  < .5;                 //chance of true
const randomBoolean = chance => Math.random() < chance;  //chance of true

The only reason to use the Math.round(Math.random()) approach is simplicity and laziness.

Solution 7 - Javascript

let try most easy solutions

 let status=Math.round(Math.random())
 console.log(status)
 if(status==1)
 {
 status=true
 }else{
 status=false
 }
 console.log(status)

Solution 8 - Javascript

How about this one?

return Math.round((Math.random() * 1) + 0) === 0;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBenView Question on Stackoverflow
Solution 1 - JavascriptCY_View Answer on Stackoverflow
Solution 2 - Javascriptuser2030471View Answer on Stackoverflow
Solution 3 - JavascriptAlexander O'MaraView Answer on Stackoverflow
Solution 4 - Javascriptuser12066722View Answer on Stackoverflow
Solution 5 - JavascriptArthur KhazbsView Answer on Stackoverflow
Solution 6 - JavascriptLeonNikolaiView Answer on Stackoverflow
Solution 7 - JavascriptRishu SinghView Answer on Stackoverflow
Solution 8 - JavascriptAlexView Answer on Stackoverflow