JS Bitwise - Math.random() * 2 被解释为 0 和 1 用于按位或 (|) 操作的规则是什么?

JS Bitwise - what are the rules of Math.random() * 2 being interpreted as 0 and 1 for purposes of bitwise Or (|) operation?

为什么要学习 http://javascriptissexy.com/javascript-apply-call-and-bind-methods-are-essential-for-javascript-professionals/ 上的 bind() 方法,我遇到了一个有趣的计算,如下所示:

var randomNum = ((Math.random () * 2 | 0) + 1) - 1;

试图理解什么 | sign 确实如此,我遇到了 JavaScript 按位运算符 (https://www.w3schools.com/js/js_bitwise.asp)。

而且我知道 (Math.random () * 2 | 0) 是按位或运算。

我了解到 Math.random() * 2 有时会根据位值给出 0 或 1 的值(例如,0.06218657045669751 被解释为 1)。我写了一个函数来检查,在哪些情况下 Math.random() * 2 计算的结果被视为 0,在哪些情况下它被视为 1:

function showNumber() {
  console.log(Math.random() * 2);

  return Math.random() * 2 | 0;
}
showNumber();

结果没有给我任何问题的答案。 因为如果 Math.random() * 2 给出 1.5337258727722651 它也可以解释为 1 和 0.

这种解释是随机的还是背后有什么逻辑?

通常,与 false (0) 的“或”运算不会做任何事情:x or false 等同于 x。与数字 0 的按位或运算也是如此。x | 0 结构只是一个 JavaScript 习语,用于将浮点数转换为整数(截断)。

因为 Math.random() * 2 是介于 0.0(含)和 2.0(不含)之间的数字,以这种方式向下舍入有 50/50 的机会是 0 或 1。

@Thomas 已经问为什么这个return是0还是1。不过,我想强调一下Math.floor| 0的区别(如评论中所述)。

在大多数情况下,这些确实会提供相同的结果,并且在大多数情况下,Math.floor 会更容易阅读和理解,尤其是对于初学者。

如果您的输入来自用户或数据库,则您无法确定输入是否真的是一个数字。 Math.floor 正确处理字符串值,但对于其他类型的值确实有一些奇怪的怪癖。

例如:Math.floor(null)returns0,而Math.floor(undefined)returnsNaN。使用按位运算符,0 在这两种情况下都会被 returned。

更进一步就是将一个对象作为输入。 Math.floor({}) returns NaN while a={}; a | 0 still returns 0 and {} | 0 实际上会抛出 SyntaxError.

一个更可信的例子是将 NaN 作为输入传递。 Math.floor 会 return NaN 而按位运算符会 return 0.

所以简而言之,按位运算符总是 return 是一个有效的 32 位整数,而 Math.floor 也可能 return NaN.