Bitwise operators changing result of arithmetic
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 开发者_C百科equal 0xFFFFFFFF, both pieces of code should return 0x100000000. Instead a get the value of 0 and b get the value of 0x100000000.
JS bitwise operators return a signed 32-bit integer. 0xFFFFFFFF gets converted to -1, and adding 1 gives 0.
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 F
s) you get the expected result.
var a = 0xFFFFFFF;
alert("a = " + a); // gives 268435455
a &= 0xFFFFFFFF;
alert("a = " + a); // gives 268435455
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
.
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
精彩评论