JS生成随机布尔值


134

简单的问题,但我对这里的细微差别感兴趣。

我使用自己想到的以下方法生成随机布尔值:

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

每当random()出现时,似乎总会有一个陷阱–它不是真正的随机性,它受到某种或其他因素的损害,等等。所以,我想知道:

a)以上是最佳做法吗?

b)我在想什么吗?

c)我在想什么吗?

d)有我不知道的更好/更快/更优雅的方式吗?

(如果B和C是互斥的,也有些兴趣。)

更新资料

如果有什么不同,我正在使用它来移动AI角色。


25
const rand = Math.random() < 0.5等价且简单。
哈姆斯

3
您只能实现随机性,而不能实现真正的随机性。
Oriol

实际上没有什么是随机的,目标是尽可能接近随机。
亚当·布坎南·史密斯

而且,如果您有50/50的机会,math.random应该会很多。只需使用毫秒作为种子。
亚当·布坎南·史密斯

我认为访问网站的时间非常随机:D所以我有了这个主意……Boolean(+Date.now()%2)
Roko C. Buljan

Answers:


337

从技术上讲,代码看起来不错,但有点太复杂了。可以比较Math.random()0.5直接,随着范围Math.random()IS [0, 1)(“在范围0到1,包括0,但不1”本装置)。您可以将范围分为[0, 0.5)[0.5, 1)

var random_boolean = Math.random() >= 0.5;

// Example
console.log(Math.random() >= 0.1) // %90 probability of get "true"
console.log(Math.random() >= 0.4) // %60 probability of get "true"
console.log(Math.random() >= 0.5) // %50 probability of get "true"
console.log(Math.random() >= 0.8) // %20 probability of get "true"
console.log(Math.random() >= 0.9) // %10 probability of get "true"


3
我喜欢这个解决方案,因为它可以让您调整
对错

例如,如果将数字0.5更改为0.9,这会增加错误的可能性吗?
特工斑马

如果将其从0.5更改为0.9。然后,可能性很可能会改变。我认为您可以尝试大量随机循环,例如10000次迭代。
开尔文

对于现代JavaScript,您应该使用 let ielet randomBool = Math.random() >= 0.5;
Chris Halcrow,


13

为了获得更安全的密码值,您可以使用 crypto.getRandomValues在现代浏览器中。

样品:

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;

请注意,该crypto对象是DOM API,因此在Node中不可用,但是Node 有类似的API


4
Math.random()众所周知在许多方面都是非随机的,还有很好的替代建议
Charles Harris

3
我要在这里添加一个小的校正,因为我发现在5亿次运行之后,它平均产生0.78%左右的零:return a [0] <= 127; (永远不包括其他127条)
Amund Midtskog,

2
@AmundMidtskog好的电话。我应该输入:a[0] > 127
Alexander O'Mara

1
顺便说一句,您通常可能希望生成比255个样本大得多的样本。相反,为了减少数据中的噪声,如另一条注释中所建议的那样,大约为100,000 –甚至数千万。您希望看到的误差小至0.78%。
caw

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

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


6
请更有用地设置其格式(stackoverflow.com/editing-help)并添加一些说明。仅代码的答案不是很欣赏。添加说明将有助于消除误解,认为StackOverflow是免费的代码编写服务。
Yunnosch

5

开尔文的回答给我留下了深刻的印象,我想提出一个相当相似但略有增强的解决方案。

var randomBoolean = Math.random() < 0.5;

该解决方案在阅读时更明显一些,因为右侧的数字<告诉您获得true而不是获得的概率false,这更容易理解。也<比短一个符号>=;



-1

亚历山大·奥玛拉的答案

只是添加节点代码片段

const crypto = require('crypto');
const randomBool = (function () {
    let a = new Uint8Array(1);
    return function () {
        crypto.randomFillSync(a);
        return a[0] > 127;
    };
})();

let trues = 0;
let falses = 0;
for (let i = 0; i < 100; i++) {
    if (randomBool()) {
        trues++;
    }
    else {
        falses++;
    }
}

console.log('true: ' + trues + ', false: ' + falses);

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.