位移与乘法

时间:2013-12-13 23:48:51

标签: javascript bit-shift multiplication

我正在尝试将字节数组转换为数字和大数字,    我看到位移正在给出-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

3 个答案:

答案 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。要超出此范围,必须使用常规算术,而不是位操作。