简单的问题,但我对这里的细微差别感兴趣。
我使用自己想到的以下方法生成随机布尔值:
const rand = Boolean(Math.round(Math.random()));
每当random()
出现时,似乎总会有一个陷阱–它不是真正的随机性,它受到某种或其他因素的损害,等等。所以,我想知道:
a)以上是最佳做法吗?
b)我在想什么吗?
c)我在想什么吗?
d)有我不知道的更好/更快/更优雅的方式吗?
(如果B和C是互斥的,也有些兴趣。)
更新资料
如果有什么不同,我正在使用它来移动AI角色。
从技术上讲,代码看起来不错,但是有点太复杂了。可以比较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) // %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"
如果您的项目有,lodash
那么您可以:
_.sample([true, false])
另外,您可以使用自己的示例函数(source):
const sample = arr => arr[Math.floor(Math.random() * arr.length)];
为了获得更安全的加密值,可以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。
!Math.round(Math.random());
开尔文的回答给我留下了深刻的印象,我想提出一个相当相似但略有增强的解决方案。
var randomBoolean = Math.random() < 0.5;
该解决方案在阅读时更明显一些,因为右侧的数字<
告诉您获得true
而不是获得的概率false
,这更容易理解。也<
比短一个符号>=
;
潜在的更快解决方案...
位运算符的方式我只是想的Math.random() + .5 >> 0
还是~~(Math.random() + .5)
。这是一项性能测试,供您自己判断。
let randomBoolean = Math.random() + .5 >> 0; //chance of true
const randomBoolean = chance => Math.random() + chance >> 0; //chance of true
在这种情况下,按位运算符基本上与使用Math.trunc()
或相同Math.floor()
,因此这也是可能的Math.trunc(Math.random() + .5)
。
let randomBoolean = Math.trunc(Math.random() + .5);
const randomBoolean = chance => Math.trunc(Math.random() + chance);
其他更常见的解决方案
获取随机布尔值的更常见方法可能是一种比较方法,例如 Math.random() >= .5
从Kelvin的答案或Math.random() < .5;
从Arthur Khazbs的答案开始,它们实际上输出的是true和false,而不是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
使用该Math.round(Math.random())
方法的唯一原因是简单和懒惰。
这个怎么样?
return Math.round((Math.random() * 1) + 0) === 0;
只是添加节点代码片段
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);
文章标签:boolean , javascript , random
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!