Bitwise operators changing result of arithmetic

2

Can somebody explain to me why the following code:

  var a = 0xFFFFFFFF;
  a &= 0xFFFFFFFF;
  a += 1;
  alert( "a = " + a );

  var b = 0xFFFFFFFF;
  b += 1;
  alert( "b = " + b );

returns different values for a and b?

Since 0xFFFFFFFF & 0xFFFFFFFF should equal 0xFFFFFFFF, both pieces of code should return 0x100000000. Instead a get the value of 0 and b get the value of 0x100000000.

javascript
math
bit-manipulation
asked on Stack Overflow Mar 17, 2011 by Sparafusile • edited Mar 17, 2011 by Sparafusile

4 Answers

3

JS bitwise operators return a signed 32-bit integer. 0xFFFFFFFF gets converted to -1, and adding 1 gives 0.

answered on Stack Overflow Mar 17, 2011 by dan04
2

Since JavaScript works with signed integers, 4294967295 can't be represented in 32 bits, thus it is converted to a wider type.

var a = 0xFFFFFFFF;
alert("a = " + a);  // gives 4294967295 (too large for a signed 32-bit integer)

a &= 0xFFFFFFFF;    // gives result as 32 bit signed integer
alert("a = " + a);  // gives -1

Details on the bitwise operators can be found here: Mozilla Developer Network: Bitwise Operators

If you initialize a to 0xFFFFFFF (thats 7 Fs) you get the expected result.

var a = 0xFFFFFFF;
alert("a = " + a);   // gives 268435455
a &= 0xFFFFFFFF;
alert("a = " + a);   // gives 268435455
answered on Stack Overflow Mar 17, 2011 by aioobe • edited Mar 17, 2011 by aioobe
0

Try this:

var a = 0xFFFFFFFF;
alert( "a = " + a );
a &= 0xFFFFFFFF;
alert( "a = " + a );
a += 1;
alert( "a = " + a );

and it should be a little more apparent what's going on. The &= is causing a type conversion that doesn't happen for b.

answered on Stack Overflow Mar 17, 2011 by Kevin
0

In JavaScript, the following expression is true:

(0xFFFFFFFF & 0xFFFFFFFF) == -1

As said by dan04, the result of boolean operations is a signed 32 bit integer value, independent of the type of the parameters. When you look at the bit-pattern of 0xFFFFFFFF and of -1, they are identical when using 32-bit values.

To always get positive results, you can add 2^32 to the result when it is negative:

function and(a, b) { let y = a & b; return (y < 0) ? (y + 0x100000000) : y;}

Then the following expression is true:

and(0xffffffff, 0xffffffff) == 0xffffffff
answered on Stack Overflow Jul 10, 2018 by Michael Dreher

User contributions licensed under CC BY-SA 3.0