HelloWorld
HelloWorld

Reputation: 3739

JavaScript bit-shifting

I would like to shift this unsigned number: 1479636484000 7 bits to the right. Is this possible in JavaScript?

Both

1479636484000 >> 7

and

1479636484000 >>> 7

returns an incorrect answer (for me). The correct answer should be 11559660031. I guess there's some sign bit involved here, and maybe the number is too large to be supported. But is there any clever way of getting around it?

Upvotes: 1

Views: 1649

Answers (3)

Cale McCollough
Cale McCollough

Reputation: 360

You will need to use BigInt to do bit-shifting of values greater than 32 signed bits.

let a = Number(BigInt(1479636484000) >> 7n);
let b = Number(BigInt(1479636484000) >>> 7n);

The reason for this is that JavaScript uses the 64-bit floating point number format, which has one sign bit, an 11-bit exponent, and 52-bit mantissa, which functions as 53 bits. JavaScirpt will truncate your number to a 32-bit signed integer.

Let's say you try the code let e = 1 << 32. This will result in the value 1, but 1 << 31 will result in -2147483648, or 0x80000000 (reminder: 0x8 = 0b1000), which is the integer value next to the lowest possible 32-bit signed value (reminder: your computer stores integers in 2's complement). 1 << 30 results in 107374182. This is terribly difficult to try to do bit shifting manually, so just use BigInt, even though it's going to be much slower.

I wish it was easier to work with 64-bit integers and bit shifting in JavaScript but you may have heard that JavaScript is a bad language, this is one of many reasons why.

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386654

You could use a string with the number and remove the last 7 characters and convert it back to a number.

console.log((1479636484000).toString(2));
console.log((11559660031).toString(2));
console.log((1479636484000).toString(2).slice(0, -7));
console.log(parseInt((1479636484000).toString(2).slice(0, -7), 2));

Upvotes: 2

Pointy
Pointy

Reputation: 413737

Bitwise operations in JavaScript start by truncating the number to a 32-bit integer. Your numbers are too big. The "clever way" to get around that limitation is to implement your own numeric library.

Note that floating-point division by 128 gets you the right answer (if you drop the fraction).

Upvotes: 2

Related Questions