Reputation: 137
I am trying convert a byte array to a number and for large numbers, I see that the bit shift is giving -ve results. Can one of you please why we see this issue? Do you see any drawbacks using "multiplication" instead of "bit-shift"?
For example,
<script language="JavaScript">
var myVar = 1000000;
document.write("Bit shift Result: " + (myVar << 8));
document.write("<br>");
document.write("Multiplication Result: " + parseInt(myVar *256));
</script>
Output:
Bit shift Result : 256000000
Multiplication Result: 256000000
Upon adding one more zero to myVar, you see the issue I am talking about
<script language="JavaScript">
var myVar = 10000000;
document.write("Bit shift Result: " + (myVar << 8));
document.write("<br>");
document.write("Multiplication Result: " + parseInt(myVar *256));
</script>
Output:
Bit shift Result: -1734967296Multiplication Result: 2560000000
Upvotes: 7
Views: 3420
Reputation: 61885
In JavaScript, all bitwise operators first invoke [ToInt32] on the operands. This includes shift operators.
Then the bitwise operators (i.e. <<
) work on signed two's-complement 32-bit integers. After the shift the resulting bit pattern represents a negative number.
00000000 10011000 10010110 10000000 - original value, after [ToInt32], as bits
10011000 10010110 10000000 00000000 - value after shift; a negative bit pattern
I would use multiplication except in cases where this behavior is desired.
(Of course, if writing a PC emulator then every little trick counts .. but prefer multiplication.)
Upvotes: 4
Reputation: 20786
Internally, JavaScript represents all numbers using 64-bit floating point with a 52-bit mantissa. However, you can also do bit operations, but only as signed 32-bit integers, which go from -2147483648 to +2147483647. To go outside of this range, you must use regular arithmetic, not bit operations.
Upvotes: 1
Reputation: 276306
To answer both your questions:
JavaScript numbers are standard IEEE doubles.
The largest integer value JavaScript can hold is: 9007199254740992
However, the bitshift operator works on 32 bit ints.
And I quote the language specification:
5 . Let lnum be ToInt32(lval).
...
Return the result of performing a sign-extending right shift of lnum by shiftCount bits. The most significant bit is propagated. The result is a signed 32-bit integer.
It still is kind of slower, but you should really avoid working directly with very large numbers in JavaScript most of the time anyway.
There are libraries that deal with very large numbers and there are features that are being discuss to add better support to large numbers to the language (ES7 value types).
Upvotes: 5