我正在使用此代码尝试找出一个数字中有多少位。下面的十六进制数字已打开所有位。
for (var i = 0x1FFFFFFFFFFFFF, m = 0; i & 1; ++m, i >>>= 1);
由于某些原因,打印m
给出了32,但在SO帖子中我读了以下内容:
JavaScript中的所有数字实际上都是符合IEEE-754标准的浮点数双精度数。它们具有53位尾数,这意味着将准确表示任何大小约为9千万亿或更小的整数值。
除非我错误地实现了这个,否则我不明白为什么打印m
在应该有53位时给出32。有人可以解释一下吗?
答案 0 :(得分: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 ) ;
确实会产生j == 53
。
另外,请注意,用于舍入的习语x | 0
不适用于大于或等于2 31 的数字。所以Math.round
通常更好。
答案 1 :(得分:5)
按位操作>>>
对32位数进行处理,因此i
实际转换为32位。有关详细信息,请参阅this。
生产ShiftExpression:ShiftExpression>>> AdditiveExpression的计算方法如下:
无符号右移运算符(>>>)
- 让lref成为评估ShiftExpression的结果。
- 让lval成为GetValue(lref)。
- 让rref成为评估AdditiveExpression的结果。
- 让rval为GetValue(rref)。
- 让lnum ToUint32(lval)。
- 让rnum ToUint32(rval)。
- 让shiftCount成为屏蔽除rnum的最低有效5位之外的所有位的结果,即计算rnum&为0x1F。
- 返回通过shiftCount位执行lnum的零填充右移的结果。空位用零填充。结果是无符号的32位整数。
醇>
答案 2 :(得分:0)
Javascript中的按位运算符可以处理32位整数。
这意味着i
中的浮点数被转换为32位整数,用于移位操作,其余位被丢弃。
参考:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators
“所有位运算符的操作数都转换为带符号的32位 整数“