Why is this bitwise AND yielding incorrect numbers? - javascript

Why does Javascript incorrectly evaluate the following?
0xAABBCCDD & 0xFF00FF00
In Javascript:
console.log((0xAABBCCDD & 0xFF00FF00).toString(16)) // -55ff3400
console.log((0xAABBCCDD & 0xFF00FF00) === 0xAA00CC00) // false
In C++:
cout << hex << (0xAABBCCDD & 0xFF00FF00) << endl; // 0xAA00CC00

As Pointy pointed out in his answer, javascript uses signed 32-bit values. You can use >>> 0 to indicate that the operation is to be unsigned.
console.log(((0xAABBCCDD & 0xFF00FF00) >>> 0).toString(16)) // Prints aa00cc00

JavaScript bitwise operations involve a coercion to 32-bit values. Your values are being truncated.
edit — sorry; as the comment pointed out it's the sign bit that's the problem.

Related

Why left-shift in JS and Dart are different?

In Javascript:
255 << 24 = -16777216
In dart:
255 << 24 = 4278190080
Is there any way by which I get the same answer in Dart similar to JS ?
To get precisely the same result in Dart as in JavaScript (whether on the web or not), do:
var jsValue = (255 << 24).toSigned(32);
JavaScript converts all bitwise operations to 32-bit integers, and to signed integers for all operators except >>>.
So, do .toSigned(32) on the result to do precisely what JavaScript does.

difference between JavaScript bit-wise operator code and Python bit-wise operator code

I have converted JavaScript code which uses bit-wise operators in that code to Python code, but there is one problem when i do this in JavaScript and Python
412287 << 10
then I get this 422181888 same results in both languages. but when i do this in both
424970184 << 10
then i get different results in both of the languages 1377771520 in JavaScript and 435169468416 in Python
can anybody help me with this?
any help would be appreciated.
If you want the JavaScript equivalent value then what you can do is :
import ctypes
print(ctypes.c_int(424970184 << 10 ^ 0).value)
Output:
1377771520
As stated in this SO answer, in javascript the bitwise operators and shift operators operate on 32-bit ints, and your second example overflows the 32 bit capacity, so the python equivalent would be:
(424970184 << 10) & 0x7FFFFFFF
(you get a "modulo"/"masked" value with the signed 32 bit integer mask, not the actual value)
In Python there's no limit in capacity for integers, so you get the actual value.

Is it correct to set bit 31 in javascript?

When I try to set 31 bit 0 | 1 << 31 I get the following result:
console.log(0 | 1 << 31); // -2147483648
Which is actualy:
console.log((-2147483648).toString(2)) // -10000000000000000000000000000000
Is it correct to set 31 bit or should I restrict to 30 to prevent negative values?
Refer to ECMA5 that the bitwise operators and shift operators operate on 32-bit ints, so in that case, the max safe integer is 2^31-1, or 2147483647.
Here is one explanation.
The << operator is defined as working on signed 32-bit integers (converted from the native Number storage of double-precision float). So 1<<31 must result in a negative number.
The only JavaScript operator that works using unsigned 32-bit integers is >>>. You can exploit this to convert a signed-integer-in-Number you've been working on with the other bitwise operators to an unsigned-integer-in-Number:
(1<<31)>>>0
Most bitwise operations are specified as converting their operands to signed 32-bit integers. It is perfectly correct to use bit 31, but yes, you'll get negative values. Usually it doesn't matter if you're doing bitwise operations anyway, since all you (should) care about is the bit pattern, not the decimal value of the number.
If you do want a positive value back, you can convert it back with >>> 0, because >>> is specified to convert its operands to unsigned 32-bit integers.
console.log((0 | 1 << 31) >>> 0);

How to apply bitwise right shift operator on binary?

How can I perform bitwise right shift on binary?
>> in JS applies to integers. So, 6 >> 1 (bitwise shift right, step 1) shows 3 as result (110 >> 1 = 011 – correct). It is nice, but... Is it possible to work with shift right operator with binary?
I need this: 110 >> 1 working correctly. This will show 55 as result and it is correct. 110 is 01101110. 01101110 >> 1 = 00110111. 00110111 is 55. Correct. But I want 011 as result! How I can do this in js?
This looks like string manipulation to me. How about:
function shr(x, s) {
return
new String('0', Math.min(s, x.length)) +
x.substr(0, Math.max(0, x.length - s));
}
>>> shr('110', 1)
'011'
Alternatively, you can use the usual bitwise operators and simply convert from a string representation beforehand (once), and convert back to a string representation afterwards (once).
Here's one way to do it:
(parseInt("110",2) >> 1).toString(2) // gives "11"
parseInt can take a radix as a parameter, so if you pass it 2 it will treat the string as binary. So you convert to a number, shift it and then use toString (which conveniently also will take a radix as a parameter) to convert back to a binary string.

Bitwise operations with big integers

I am implementing decoding of BER-compressed integers and recently I've found a weird JavaScript behavior related to bitwise operations with big integers.
E.g.:
var a = 17516032; // has 25 bits
alert(a << 7) // outputs -2052915200
alert(a * 128) // outputs 2242052096
alert(2242052096 >> 16) // outputs -31325
alert(2242052096 / 65536) // outputs 34211
While the first workaround (multiplication instead of left shift) is acceptable, the second isn't.
Why it happens? How to bear with it?
17516032 in binary is 00000001000010110100011000000000. Shifting to the left by 7 gives you 10000101101000110000000000000000. This is equal to -2052915200 in two's complement (which is how almost all computers represent negative numbers).
>> is a signed right shift. That means that the leftmost bit (which determines the sign of a number) will be shifted into the left side.
e.g.
1100 >> 2 == 1111
0111 >> 2 == 0001
If you want to do an unsigned shift (which ignores the sign bit), use >>> which will zero-fill the left end of the bitstring.
Bitwise operators work on 32 bit integers, while multiplication and division works on floating point numbers.
When you shift a number, it's converted from a floating point number to a 32 bit integer before the operations, and converted back to a floating point number after the operation. The number 2242052096 has the 32nd bit set, so it is a negative number when converted to and from a 32 bit integer.
The >> right shift operator doesn't change the sign of the value, i.e. the bits that are shifted in from the left have the same value as the sign bit. Use the >>> right shift operator to shift in zero bits instead.
Reference: MDN: Bitwise operators
(2242052096 / 65536) == (2242052096 >>> 16)
Note the different shift.
Javascript normally represents numbers as (double-precision) floating point.
Almost all bitwise operations convert to a signed 32-bit integer, do whatever they're going to do, then treat the result as a signed 32-bit integer when converting back.
The exception is >>> which treats the result as an unsigned 32-bit integer when converting back.
So:
right shifts can be made to work simply by using >>> instead of >> ;
a * 128 gives the expected answer because it's never converted to a signed 32-bit integer in the first place - it's just a floating-point multiplication;
a << 7 gives an unexpected answer because it's converted to a signed 32-bit integer, and then you shift a 1 into the sign bit, resulting in a negative signed 32-bit value.
There isn't a <<<, but if you want to write your left shift as a shift, you can use
(a << 7) >>> 0
to get the expected answer (the >>> 0 effectively casts the signed 32-bit value to an unsigned 32-bit value).

Categories

Resources