user3101143
user3101143

Reputation: 137

bit shift vs multiplication

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: -1734967296

Multiplication Result: 2560000000

Upvotes: 7

Views: 3420

Answers (3)

user2864740
user2864740

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

Matt
Matt

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

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276306

To answer both your questions:

Can one of you please why we see this issue?

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.

Do you see any drawbacks using "multiplication" instead of "bit-shift"?

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

Related Questions