lei lei
lei lei

Reputation: 1829

how to get bitwise or operator work correctly in Javascript

I have a javascript program there use bitwise OR operator to get a OR result from two numbers:

Sample code:

<!DOCTYPE html>
<html>
<body>

<p>Click the button to return the number of characters in the string "Hello World!".</p>

<button onclick="myFunction()">Try it</button>

<p id="demo"></p>

<script>
function myFunction() {
    var str = "80400001";
    var a = parseInt(str, 16);
    var str = "12345678";
    var b = parseInt(str, 16);
    n = b|a;
    document.getElementById("demo").innerHTML = n;
}
</script>

</body>
</html>

But the result is always negative, that is not my expected value. Result:

-1837869447

Eventhough I try to OR a number with zero, the result is still negative...

It doesn't happen in Java, but in Javascript.

Can you tell how can I get the same result as that in Java?

Upvotes: 2

Views: 194

Answers (3)

Chris Li
Chris Li

Reputation: 2671

The reason is because number in javascript is 64bit floating point, but bitwise operator work on 32bit int, in your example variable a is larger than 31^2, so when you apply a bitwise operator it changed to negative. One way I can think of around it is to use unsigned right shift to push off the signed bit, and add back the bit pushed off.

var str = "80400001";
var a = parseInt(str, 16);
var str = "12345678";
var b = parseInt(str, 16);
n = parseInt(((a|b) >>> 1).toString(2) + (a%2|b%2), 2);
console.log(n)

Upvotes: 2

cyrilluce
cyrilluce

Reputation: 985

You can use this change signed int to unsigned int:

n>>>0

var str = "80400001";
var a = parseInt(str, 16);
var str = "12345678";
var b = parseInt(str, 16);
n = b | a;
    
console.log((n>>>0).toString(16))

see: Bitwise operations on 32-bit unsigned ints?

Upvotes: 4

Jared Smith
Jared Smith

Reputation: 21936

I believe the problem is that unlike e.g. Java and Python JavaScript does not have a 64 bit integer type. When you use the bitwise operators in JS, the number is truncated to 32 bits, the operation is performed, then it is cast back to an IEEE 754 float. 0x80400001 is 2,151,677,953 which is bigger than 2,147,483,647 (max signed 32 bit int) and you're losing the significant bits which is giving the odd result.

There are arbitrary size integer libraries one can use.

Also checkout cyrilluce's answer for a way to do it without an external lib.

Upvotes: 3

Related Questions