我只是在摆弄javascript而且我使用Math.random编写了函数,我认为它会返回一个硬币翻转。然后我很好奇,所以我通过一个循环来测试它翻转true / false的频率。我发现我的循环正在跳过大约一半的其他条件,并且能够通过在错误var中捕获它们来验证这一点。那么,为什么要这样做呢?
var truths = 0;
var alternativetruths = 0;
var errors = 0;
function game() {
var score = Math.random()*10;
return score>5;
}
for(i=0;i<999999;i++) {
if (game() === true) {
truths++
} else if (game() === false) {
alternativetruths++
} else {
errors++
}
}
console.log("truths:",truths,"alternativetruths:",alternativetruths,"errors:",errors)
真理:500393 alternativetruths:249580错误:250026
答案 0 :(得分:9)
您的代码调用game()
两次。如果第一个电话不是 true
,那么第二个电话可能是true
,也可能不是。{/ p>
只需拨打game()
一次,然后将结果分配给变量即可。不要与true
和false
进行明确比较; if
语句可以解决布尔值,并且您的函数已经返回其中一个。
for (var i = 0; i < 999999; i++) {
var result = game();
if (result)
truths++;
else
alternativetruths++;
}
答案 1 :(得分:3)
因为您正在调用game
两次,因此会获得两个不同的随机标记。
最小的变化是记住数字:
for(i=0;i<999999;i++) {
var flag = game();
if (flag === true) {
truths++
} else if (flag === false) {
alternativetruths++
} else {
errors++
}
}
但其他一些说明:
flag
是布尔值(并且它是>
运算符的结果),则if (flag === true)
毫无意义。只需使用if (flag)
即可。 ===
运算符的结果也是布尔值,所以如果你不相信它们是真或假,你在哪里停止? :-) if ((flag === true) === true)
?if (flag === false)
应为if (!flag)
。flag
是布尔值(并且是),那么如果您有if (flag)
,则else if (!flag)
然后else
没有任何意义。您无法达到最终else
。只需if (flag) { } else { }
即可。game
并不公平,它有 非常轻微 偏向返回{{1} }。请注意,false
返回的范围为Math.random() * 10
,不到10,因此检查0
表示您正在跳过中点。因为你处理的是非常小的分数,所以你没有注意到这种偏见,但它就在那里;如果你四舍五入到整数,这将是更明显的,在这一点上它将是大约40%/ 60%真/假。您希望> 5
获得公平的结果。>= 5
可以简洁地写成:game
。return Math.random() >= 0.5;
,所以您会成为The Horror of Implicit Globals 的牺牲品(我的贫血小博客上的帖子) 。记得声明你的变量。重新i
与>
,这里有一个例子,我将四舍五入到整数以使效果更清晰:
>=
&#13;
for (var n = 0; n < 4; ++n) {
setTimeout(test.bind(null, n, true), 200 * n);
setTimeout(test.bind(null, n, false), 200 * n + 100);
}
function test(num, gte) {
var truths = 0;
var alternativetruths = 0;
var errors = 0;
function game() {
var score = Math.floor(Math.random() * 10);
return gte ? score >= 5 : score > 5;
}
for (var i = 0; i < 999999; i++) {
var flag = game();
if (flag) {
truths++;
} else {
alternativetruths++;
}
}
showStats(num, gte, truths, alternativetruths);
}
function showStats(num, gte, truths, alternativetruths) {
var total = truths + alternativetruths; // Should be 999999 of course
var truthsPercent = (truths * 100) / total;
var altPercent = (alternativetruths * 100) / total;
console.log(num, gte ? ">=" : ">", "truths:", truths, "alternativetruths:", alternativetruths, "(" + truthsPercent.toFixed(2) + "% vs. " + altPercent.toFixed(2) + "%)");
}
&#13;
答案 2 :(得分:0)
您需要在测试前为游戏分配游戏的值。否则,每次使用game()检查值时,您都会检查一个新值。所以在第一次检查时它可能是假的,在第二次检查时可能是真的,因此增加了你的错误。 试试这个:
for(i=0;i<999999;i++) {
let gameResult = game();
if (gameResult === true) {
truths++
} else if (gameResult === false) {
alternativetruths++
} else {
errors++
}
}