简单的问题,但我对这里的细微差别感兴趣。
我使用我自己提出的以下方法生成随机布尔值:
const rand = Boolean(Math.round(Math.random()));
每当random()
出现时,似乎总是存在陷阱 - 它不是真正随机的,它会受到某种或其他因素的影响等等。所以,我&#39 ;我想知道:
a)以上是最好的做法吗?
b)我是否过度思考事物?c)我是否解开了事情?
d)我不知道更好/更快/更优雅的方式吗?
(如果B和C相互排斥,也有点感兴趣。)
更新
如果它有所作为,我会用它来移动AI角色。
答案 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;
请注意,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 answer的Math.trunc(Math.random() + .5)
或Arthur Khazbs's answer的let 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)
仅添加节点代码段
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()))