JS生成随机布尔值

时间:2016-04-20 22:27:54

标签: javascript random boolean

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

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

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

每当random()出现时,似乎总是存在陷阱 - 它不是真正随机的,它会受到某种或其他因素的影响等等。所以,我&#39 ;我想知道:

a)以上是最好的做法吗?

b)我是否过度思考事物?

c)我是否解开了事情?

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

(如果B和C相互排斥,也有点感兴趣。)

更新

如果它有所作为,我会用它来移动AI角色。

9 个答案:

答案 0 :(得分:216)

从技术上讲,代码看起来很好,但有点太复杂了。 你可以比较" Math.random()"至" 0.5"直接,因为Math.random()的范围是[0,1]。您可以将范围分为[0,0.5)和[0.5,1]。

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

答案 1 :(得分:19)

如果您的项目有lodash,那么您可以:

_.sample([true, false])

答案 2 :(得分:11)

要获得更加加密的安全值,您可以在现代浏览器中使用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;
&#13;
&#13;
&#13;

请注意,crypto对象是DOM API,因此它在节点中不可用,但there is a similar API for Node

答案 3 :(得分:6)

Kelvin's answer对我印象深刻,我想提出一个相当相似但略有增强的解决方案。

var randomBoolean = Math.random() < 0.5;

这种解决方案在阅读上更为明显,因为<右侧的数字告诉您获得true而不是获得false的概率,更自然。另外,<>=短一个符号;

答案 4 :(得分:2)

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

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

答案 5 :(得分:1)

潜在的更快解决方案...

按位运算符方法我刚刚想到了@Entity @Table(name = "student") data class Student( var name: String = "", @ManyToMany(cascade = [CascadeType.ALL]) @JoinTable(name = "student_subject", joinColumns = [JoinColumn(name = "student_id", referencedColumnName = "id")], inverseJoinColumns = [JoinColumn(name = "subject_id", referencedColumnName = "id")]) var subjects: List<Subject> = mutableListOf<Subject>(), @Id @GeneratedValue(strategy = GenerationType.AUTO) var id: Long = -1 ){ override fun toString(): String{ return "{student: ${this.name}, subjects: ${subjects.map { it->it.name }}}"; } } @Entity @Table(name = "subject") data class Subject( @Id var id: Long = -1, var name: String = "", @ManyToMany(mappedBy = "subjects") var students: List<Student> = mutableListOf<Student>() ){ override fun toString(): String{ return "{subject: ${this.name}, students: ${students.map { it->it.name }}}"; } }2020-08-03 22:16:37.984 WARN 9468 --- [nio-5000-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Failure while trying to resolve exception [org.springframework.http.converter.HttpMessageNotWritableException] java.lang.IllegalStateException: Cannot call sendError() after the response has been committed at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:472) ~[tomcat-embed-core-9.0.37.jar:9.0.37] at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178) ~[jackson-databind-2.11.1.jar:2.11.1] .1] at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:107) ~[jackson-databind-2.11.1.jar:2.11.1] at com.fasterxml.jackson.databind.ser.std.CollectionSerializer.serialize(CollectionSerializer.java:25) ~[jackson-databind-2.11.1.jar:2.11.1] at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.11.1.jar:2.11.1] at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:755) ~[jackson-databind-2.11.1.jar:2.11.1] 2020-08-03 22:16:38.016 ERROR 9468 --- [nio-5000-exec-2] s.e.ErrorMvcAutoConfiguration$StaticView : Cannot render error page for request [/v1/api/order] and exception [] as the response has already been committed. As a result, the response may have the wrong status code.。这是一个performance test来自己判断。

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()

其他更常见的解决方案

获取随机布尔值的更常见方法可能是比较方法,例如Kelvin's answerMath.trunc(Math.random() + .5)Arthur Khazbs's answerlet randomBoolean = Math.trunc(Math.random() + .5); const randomBoolean = chance => Math.trunc(Math.random() + chance); ,它们实际上输出true和false,而不是true和false。 1&0。

Math.random() >= .5

使用Math.random() < .5;方法的唯一原因是简单和懒惰。

答案 6 :(得分:0)

这个怎么样?

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

答案 7 :(得分:0)

答案Alexander O'Mara

仅添加节点代码段

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);

答案 8 :(得分:-1)

另一种解决方法:

Boolean(Math.round(Math.random()))