Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bitwise AND in Javascript with a 64 bit integer

I am looking for a way of performing a bitwise AND on a 64 bit integer in JavaScript.

JavaScript will cast all of its double values into signed 32-bit integers to do the bitwise operations (details here).

like image 770
Toby Hede Avatar asked Jun 06 '10 05:06

Toby Hede


People also ask

Does JavaScript support 64-bit integers?

Since JavaScript does not natively support 64-bit integers, 64-bit Ids are instead represented as strings. Strings containing 64-bit Ids are distinguished from ordinary strings through use of the Id64String type alias.

Can JavaScript handle int64?

JavaScript Numbers are represented as IEEE 754 double-precision floats. Unfortunately, this means they lose integer precision for values beyond +/- 2^^53. For projects that need to accurately handle 64-bit ints, such as node-thrift, a performant, Number-like class is needed.

What is Bitwise and in JavaScript?

The bitwise AND operator ( & ) returns a 1 in each bit position for which the corresponding bits of both operands are 1 s.


1 Answers

Javascript represents all numbers as 64-bit double precision IEEE 754 floating point numbers (see the ECMAscript spec, section 8.5.) All positive integers up to 2^53 can be encoded precisely. Larger integers get their least significant bits clipped. This leaves the question of how can you even represent a 64-bit integer in Javascript -- the native number data type clearly can't precisely represent a 64-bit int.

The following illustrates this. Although javascript appears to be able to parse hexadecimal numbers representing 64-bit numbers, the underlying numeric representation does not hold 64 bits. Try the following in your browser:

<html>   <head>     <script language="javascript">       function showPrecisionLimits() {         document.getElementById("r50").innerHTML = 0x0004000000000001 - 0x0004000000000000;         document.getElementById("r51").innerHTML = 0x0008000000000001 - 0x0008000000000000;         document.getElementById("r52").innerHTML = 0x0010000000000001 - 0x0010000000000000;         document.getElementById("r53").innerHTML = 0x0020000000000001 - 0x0020000000000000;         document.getElementById("r54").innerHTML = 0x0040000000000001 - 0x0040000000000000;       }     </script>   </head>   <body onload="showPrecisionLimits()">     <p>(2^50+1) - (2^50) = <span id="r50"></span></p>     <p>(2^51+1) - (2^51) = <span id="r51"></span></p>     <p>(2^52+1) - (2^52) = <span id="r52"></span></p>     <p>(2^53+1) - (2^53) = <span id="r53"></span></p>     <p>(2^54+1) - (2^54) = <span id="r54"></span></p>   </body> </html> 

In Firefox, Chrome and IE I'm getting the following. If numbers were stored in their full 64-bit glory, the result should have been 1 for all the substractions. Instead, you can see how the difference between 2^53+1 and 2^53 is lost.

(2^50+1) - (2^50) = 1 (2^51+1) - (2^51) = 1 (2^52+1) - (2^52) = 1 (2^53+1) - (2^53) = 0 (2^54+1) - (2^54) = 0 

So what can you do?

If you choose to represent a 64-bit integer as two 32-bit numbers, then applying a bitwise AND is as simple as applying 2 bitwise AND's, to the low and high 32-bit 'words'.

For example:

var a = [ 0x0000ffff, 0xffff0000 ]; var b = [ 0x00ffff00, 0x00ffff00 ]; var c = [ a[0] & b[0], a[1] & b[1] ];  document.body.innerHTML = c[0].toString(16) + ":" + c[1].toString(16); 

gets you:

ff00:ff0000 
like image 150
Oren Trutner Avatar answered Sep 22 '22 08:09

Oren Trutner