我正在尝试将字节数组转换为数字和大数字, 我看到位移正在给出-ve结果。 你们其中一个人可以为什么我们看到这个问题?您是否看到使用“乘法”而不是“位移”的任何缺点?
例如,
<script language="JavaScript">
var myVar = 1000000;
document.write("Bit shift Result: " + (myVar << 8));
document.write("<br>");
document.write("Multiplication Result: " + parseInt(myVar *256));
</script>
输出:
位移结果:256000000
乘法结果:256000000
在向myVar添加一个零后,您会看到我正在讨论的问题
<script language="JavaScript">
var myVar = 10000000;
document.write("Bit shift Result: " + (myVar << 8));
document.write("<br>");
document.write("Multiplication Result: " + parseInt(myVar *256));
</script>
输出:
位移结果: -1734967296乘法结果:2560000000
答案 0 :(得分:3)
在JavaScript中,所有按位运算符首先在操作数上调用[ToInt32]。这包括转移运营商。
然后,按位运算符(即<<
)处理带符号 two's-complement 32位整数。移位后,结果位模式表示负数。
00000000 10011000 10010110 10000000 - original value, after [ToInt32], as bits
10011000 10010110 10000000 00000000 - value after shift; a negative bit pattern
除了需要这种行为的情况外,我会使用乘法。
(当然,如果写一个PC emulator,那么每一个小技巧都会重要..但更喜欢乘法。)
答案 1 :(得分:3)
回答你的两个问题:
JavaScript编号是标准的IEEE双精度数。
JavaScript可容纳的最大整数值为:9007199254740992
然而,bitshift运算符以32位整数运行。
我引用the language specification:
5。让lnum成为ToInt32(lval)。
...
返回通过shiftCount位执行lnum符号扩展右移的结果。传播最重要的位。结果是带符号的32位整数。
它仍然有点慢,但你绝对应该避免在大多数情况下直接使用JavaScript中的非常大的数字。
有些库可以处理非常大的数字,并且正在讨论一些功能,以便为语言增加对大数字的更好支持(ES7值类型)。
答案 2 :(得分:1)
在内部,JavaScript表示使用64位浮点和52位尾数的所有数字。但是,您也可以执行位操作,但仅作为带符号的32位整数,从-2147483648到+2147483647。要超出此范围,必须使用常规算术,而不是位操作。