为什么这个代码为数字中的位(而不是53)提供32?

Me *_*d I 3 javascript

我正在使用此代码来尝试找出一个数字中有多少位.下面的十六进制数字已打开所有位.

for (var i = 0x1FFFFFFFFFFFFF, m = 0; i & 1; ++m, i >>>= 1);
Run Code Online (Sandbox Code Playgroud)

出于某种原因打印m给出32,但在SO帖子中我读了以下内容:

JavaScript中的所有数字实际上都是符合IEEE-754标准的浮点数双精度数.它们具有53位尾数,这意味着将精确表示任何大小约为9千万亿或更小的整数值.

除非我错误地实现了这个,否则我不明白为什么m当应该有53位时打印给出32.有人可以解释一下吗?

Pot*_*ter 6

按位操作由JavaScript/ECMAScript标准指定,以便在发生任何其他事件之前将数字截断为31位(向零舍入,将模数取为2 32,并将最高有效位解释为二进制补码).所以你需要使用简单算术重新编码它.

这部分是因为处理小数的FPU可能无法在逻辑电路级实现按位运算.

最天真的测试方法是for ( var i = 0; i != i + 1; ++ i ) ;在我尝试时崩溃了Firefox.(期待暂停,但是没有!)稍微更具体的单线

for ( var i = 1, j = 0; i != i + 1; i *= 2, ++ j ) ;
Run Code Online (Sandbox Code Playgroud)

收益率j == 53.

另外,请注意,x | 0舍入的习惯用法不适用于大于或等于2 31的数字.所以Math.round通常更好.


Ona*_*Bai 5

按位操作为>>>32位数字,因此i实际转换为32位.有关更多信息,请参阅

指示:

生产ShiftExpression:ShiftExpression >>> AdditiveExpression的计算方法如下:

无符号右移运算符(>>>)

  1. 让lref成为评估ShiftExpression的结果.
  2. 设lval为GetValue(lref).
  3. 让rref成为评估AdditiveExpression的结果.
  4. 设rval为GetValue(rref).
  5. 让lnum成为ToUint32(lval).
  6. 让rnum成为ToUint32(rval).
  7. 设shiftCount是屏蔽除rnum的最低有效5位之外的所有位的结果,即计算rnum和0x1F.
  8. 返回通过shiftCount位执行lnum的零填充右移的结果.空位用零填充.结果是无符号的32位整数.