How to make Javascript bitwise operators behave like in C? - javascript

In Javascript the following comparison:
(0xf0000000 & 0xf0000000) == 0xf0000000
is false since the bitwise operator converts to numbers to signed int32. The result of the & is a negative number and 0xf0000000 is a positive number
Is there a way to make it behave as I would expect it to behave in C?

Section 12.9.5 of Ecma 262 7.0 (ES 2016) defines the unsigned right shift operator (>>>) to return a unsigned 32-bit integer. This has been the case at least since ES 5.
In other words, you can use this operator to turn a int32 value into a uint32 value when you shift by 0.
Therefore, you can simply change the expression to
(0xf0000000 & 0xf0000000) >>> 0 == 0xf0000000
which yields true.

Use the XOR operator and compare with 0.
(0xf0000000 & 0xf0000000) ^ 0xf0000000 === 0
A ^ B will be 0 if A === B.

Related

How is the Number of value 0x80000000 organised in JavaScript? [duplicate]

Doing some tests with bitwise operations / shifting with JavaScript
0x80000000 >> 1 // returns -1073741824 (-0x40000000)
I would expect that to return 0x40000000 since
0x40000000 >> 1 // returns 0x20000000
0x20000000 >> 1 // returns 0x10000000
Its an arithmetic shift that's why the sign is preserved, to do a logical shift use >>>
0x80000000 >>> 1 // returns 1073741824 (0x40000000)
In Javascript, >> is the Signed Right Shift Operator. In §11.7.2 of the language specification it says:
Performs a sign-filling bitwise right shift operation on the left operand by the amount specified by the right operand.
Before the shifting is done, the left operand is converted to a signed 32-bit integer (step 5 of the algorithm given in the specification). In your case this conversion turns the given positive number into a negative value. After that, the actual shifting is done, preserving the negative sign of the value.

what is the purpose of number >>> 0 in javascript? [duplicate]

I was looking at code from Mozilla that add a filter method to Array and it had a line of code that confused me.
var len = this.length >>> 0;
I have never seen >>> used in JavaScript before. What is it and what does it do?
It doesn't just convert non-Numbers to Number, it converts them to Numbers that can be expressed as 32-bit unsigned ints.
Although JavaScript's Numbers are double-precision floats(*), the bitwise operators (<<, >>, &, | and ~) are defined in terms of operations on 32-bit integers. Doing a bitwise operation converts the number to a 32-bit signed int, losing any fractions and higher-place bits than 32, before doing the calculation and then converting back to Number.
So doing a bitwise operation with no actual effect, like a rightward-shift of 0 bits >>0, is a quick way to round a number and ensure it is in the 32-bit int range. Additionally, the triple >>> operator, after doing its unsigned operation, converts the results of its calculation to Number as an unsigned integer rather than the signed integer the others do, so it can be used to convert negatives to the 32-bit-two's-complement version as a large Number. Using >>>0 ensures you've got an integer between 0 and 0xFFFFFFFF.
In this case this is useful because ECMAScript defines Array indexes in terms of 32 bit unsigned ints. So if you're trying to implement array.filter in a way that exactly duplicates what the ECMAScript Fifth Edition standard says, you would cast the number to 32-bit unsigned int like this.
In reality there's little practical need for this as hopefully people aren't going to be setting array.length to 0.5, -1, 1e21 or 'LEMONS'.
Summary:
1>>>0 === 1
-1>>>0 === 0xFFFFFFFF -1>>0 === -1
1.7>>>0 === 1
0x100000002>>>0 === 2
1e21>>>0 === 0xDEA00000 1e21>>0 === -0x21600000
Infinity>>>0 === 0
NaN>>>0 === 0
null>>>0 === 0
'1'>>>0 === 1
'x'>>>0 === 0
Object>>>0 === 0
(*: well, they're defined as behaving like floats. It wouldn't surprise me if some JavaScript engine actually used ints when it could, for performance reasons. But that would be an implementation detail you wouldn't get to take any advantage of.)
The unsigned right shift operator is used in the all the array extra's method implementations of Mozilla, to ensure that the length property is a unsigned 32-bit integer.
The length property of array objects is described in the specification as:
Every Array object has a length property whose value is always a nonnegative integer less than 232.
This operator is the shortest way to achieve it, internally array methods use the ToUint32 operation, but that method is not accessible and exist on the specification for implementation purposes.
The Mozilla array extras implementations try to be ECMAScript 5 compliant, look at the description of the Array.prototype.indexOf method (§ 15.4.4.14):
1. Let O be the result of calling ToObject passing the this value
as the argument.
2. Let lenValue be the result of calling the [[Get]] internal method of O with
the argument "length".
3. Let len be ToUint32(lenValue).
....
As you can see, they just want to reproduce the behavior of the ToUint32 method to comply with the ES5 spec on an ES3 implementation, and as I said before, the unsigned right shift operator is the easiest way.
That is the unsigned right bit shift operator. The difference between this and the signed right bit shift operator, is that the unsigned right bit shift operator (>>>) fills with zeroes from the left, and the signed right bit shift operator (>>) fills with the sign bit, thus preserving the sign of the numerical value when shifted.
Driis has sufficiently explained what the operator is and what it does. Here's the meaning behind it/why it was used:
Shifting any direction by 0 does returns the original number and will cast null to 0. It seems that the example code that you are looking at is using this.length >>> 0 to ensure that len is numeric even if this.length is not defined.
For many people, bitwise operations are unclear (and Douglas Crockford/jslint suggests against using such things). It doesn't mean that its wrong to do, but more favorable and familiar methods exist to make code more readable. A more clear way to ensure that len is 0 is either of the following two methods.
// Cast this.length to a number
var len = +this.length;
or
// Cast this.length to a number, or use 0 if this.length is
// NaN/undefined (evaluates to false)
var len = +this.length || 0;
>>> is the unsigned right shift operator (see p. 76 of the JavaScript 1.5 specification), as opposed to the >>, the signed right shift operator.
>>> changes the results of shifting negative numbers because it does not preserve the sign bit when shifting. The consequences of this is can be understood by example, from an interpretter:
$ 1 >> 0
1
$ 0 >> 0
0
$ -1 >> 0
-1
$ 1 >>> 0
1
$ 0 >>> 0
0
$ -1 >>> 0
4294967295
$(-1 >>> 0).toString(16)
"ffffffff"
$ "cabbage" >>> 0
0
So what is probably intended to be done here is to get the length, or 0 if the length is undefined or not an integer, as per the "cabbage" example above. I think in this case it is safe to assume that this.length will never be < 0. Nevertheless, I would argue that this example is a nasty hack, for two reasons:
The behavior of <<< when using negative numbers, a side-effect probably not intended (or likely to occur) in the example above.
The intention of the code is not obvious, as the existence of this question verifies.
Best practice is probably to use something more readable unless performance is absolutely critical:
isNaN(parseInt(foo)) ? 0 : parseInt(foo)
Two reasons:
The result of >>> is an "integral"
undefined >>> 0 = 0 (since JS will try and coerce the LFS to numeric context, this will work for "foo" >>> 0, etc. as well)
Remember that numbers in JS have an internal-representation of double.
It's just a "quick" way of basic input sanity for length.
However, -1 >>> 0 (oops, likely not a desired length!)
Sample Java Code below explains well:
int x = 64;
System.out.println("x >>> 3 = " + (x >>> 3));
System.out.println("x >> 3 = " + (x >> 3));
System.out.println(Integer.toBinaryString(x >>> 3));
System.out.println(Integer.toBinaryString(x >> 3));
Output is the following:
x >>> 3 = 536870904
x >> 3 = -8
11111111111111111111111111000
11111111111111111111111111111000

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);

What does the combination of !!~ do? [duplicate]

If you read the comments at the jQuery inArray page here, there's an interesting declaration:
!!~jQuery.inArray(elm, arr)
Now, I believe a double-exclamation point will convert the result to type boolean, with the value of true. What I don't understand is what is the use of the tilde (~) operator in all of this?
var arr = ["one", "two", "three"];
if (jQuery.inArray("one", arr) > -1) { alert("Found"); }
Refactoring the if statement:
if (!!~jQuery.inArray("one", arr)) { alert("Found"); }
Breakdown:
jQuery.inArray("one", arr) // 0
~jQuery.inArray("one", arr) // -1 (why?)
!~jQuery.inArray("one", arr) // false
!!~jQuery.inArray("one", arr) // true
I also noticed that if I put the tilde in front, the result is -2.
~!!~jQuery.inArray("one", arr) // -2
I don't understand the purpose of the tilde here. Can someone please explain it or point me towards a resource?
There's a specfic reason you'll sometimes see ~ applied in front of $.inArray.
Basically,
~$.inArray("foo", bar)
is a shorter way to do
$.inArray("foo", bar) !== -1
$.inArray returns the index of the item in the array if the first argument is found, and it returns -1 if its not found. This means that if you're looking for a boolean of "is this value in the array?", you can't do a boolean comparison, since -1 is a truthy value, and when $.inArray returns 0 (a falsy value), it means its actually found in the first element of the array.
Applying the ~ bitwise operator causes -1 to become 0, and causes 0 to become `-1. Thus, not finding the value in the array and applying the bitwise NOT results in a falsy value (0), and all other values will return non-0 numbers, and will represent a truthy result.
if (~$.inArray("foo", ["foo",2,3])) {
// Will run
}
And it'll work as intended.
!!~expr evaluates to false when expr is -1 otherwise true.
It is same as expr != -1, only broken*
It works because JavaScript bitwise operations convert the operands to 32-bit signed integers in two's complement format. Thus !!~-1 is evaluated as follows:
-1 = 1111 1111 1111 1111 1111 1111 1111 1111b // two's complement representation of -1
~-1 = 0000 0000 0000 0000 0000 0000 0000 0000b // ~ is bitwise not (invert all bits)
!0 = true // ! is logical not (true for falsy)
!true = false // duh
A value other than -1 will have at least one bit set to zero; inverting it will create a truthy value; applying ! operator twice to a truthy value returns boolean true.
When used with .indexOf() and we only want to check if result is -1 or not:
!!~"abc".indexOf("d") // indexOf() returns -1, the expression evaluates to false
!!~"abc".indexOf("a") // indexOf() returns 0, the expression evaluates to true
!!~"abc".indexOf("b") // indexOf() returns 1, the expression evaluates to true
* !!~8589934591 evaluates to false so this abomination cannot be reliably used to test for -1.
The tilde operator isn't actually part of jQuery at all - it's a bitwise NOT operator in JavaScript itself.
See The Great Mystery of the Tilde(~).
You are getting strange numbers in your experiments because you are performing a bitwise logical operation on an integer (which, for all I know, may be stored as two's complement or something like that...)
Two's complement explains how to represent a number in binary. I think I was right.
~foo.indexOf(bar) is a common shorthand to represent foo.contains(bar) because the contains function doesn't exist.
Typically the cast to boolean is unnecessary due to JavaScript's concept of "falsy" values. In this case it's used to force the output of the function to be true or false.
jQuery.inArray() returns -1 for "not found", whose complement (~) is 0. Thus, ~jQuery.inArray() returns a falsy value (0) for "not found", and a truthy value (a negative integer) for "found". !! will then formalise the falsy/truthy into real boolean false/true. So, !!~jQuery.inArray() will give true for "found" and false for "not found".
The ~ for all 4 bytes int is equal to this formula -(N+1)
SO
~0 = -(0+1) // -1
~35 = -(35+1) // -36
~-35 = -(-35+1) //34
Tilde is bitwise NOT - it inverts each bit of the value. As a general rule of thumb, if you use ~ on a number, its sign will be inverted, then 1 will be subtracted.
Thus, when you do ~0, you get -1 (0 inverted is -0, subtract 1 is -1).
It's essentially an elaborate, super-micro-optimised way of getting a value that's always Boolean.
The ~ operator is the bitwise complement operator. The integer result from inArray() is either -1, when the element is not found, or some non-negative integer. The bitwise complement of -1 (represented in binary as all 1 bits) is zero. The bitwise-complement of any non-negative integer is always non-zero.
Thus, !!~i will be true when integer "i" is a non-negative integer, and false when "i" is exactly -1.
Note that ~ always coerces its operand to integer; that is, it forces non-integer floating point values to integer, as well as non-numeric values.
You're right: This code will return false when the indexOf call returns -1; otherwise true.
As you say, it would be much more sensible to use something like
return this.modifiedPaths.indexOf(path) !== -1;
The ~ operator is the bitwise NOT operator. What this means is that it takes a number in binary form and turns all zeroes into ones and ones into zeroes.
For instance, the number 0 in binary is 0000000, while -1 is 11111111. Likewise, 1 is 00000001 in binary, while -2 is 11111110.
My guess is that it is there because it's a few characters shorter (which library authors are always after). It also uses operations that only take a few machine cycles when compiled into the native code (as opposed to the comparison to a number.)
I agree with another answer that it's an overkill but perhaps might make sense in a tight loop (requires performance gain estimation, though, otherwise may turn out to be premature optimization.)
I assume, since it is a bitwise operation, it is the fastest (computationally cheap) way to check whether path appears in modifiedPaths.
As (~(-1)) === 0, so:
!!(~(-1)) === Boolean(~(-1)) === Boolean(0) === false

Javascript: Why use >>> 0 [duplicate]

I was looking at code from Mozilla that add a filter method to Array and it had a line of code that confused me.
var len = this.length >>> 0;
I have never seen >>> used in JavaScript before. What is it and what does it do?
It doesn't just convert non-Numbers to Number, it converts them to Numbers that can be expressed as 32-bit unsigned ints.
Although JavaScript's Numbers are double-precision floats(*), the bitwise operators (<<, >>, &, | and ~) are defined in terms of operations on 32-bit integers. Doing a bitwise operation converts the number to a 32-bit signed int, losing any fractions and higher-place bits than 32, before doing the calculation and then converting back to Number.
So doing a bitwise operation with no actual effect, like a rightward-shift of 0 bits >>0, is a quick way to round a number and ensure it is in the 32-bit int range. Additionally, the triple >>> operator, after doing its unsigned operation, converts the results of its calculation to Number as an unsigned integer rather than the signed integer the others do, so it can be used to convert negatives to the 32-bit-two's-complement version as a large Number. Using >>>0 ensures you've got an integer between 0 and 0xFFFFFFFF.
In this case this is useful because ECMAScript defines Array indexes in terms of 32 bit unsigned ints. So if you're trying to implement array.filter in a way that exactly duplicates what the ECMAScript Fifth Edition standard says, you would cast the number to 32-bit unsigned int like this.
In reality there's little practical need for this as hopefully people aren't going to be setting array.length to 0.5, -1, 1e21 or 'LEMONS'.
Summary:
1>>>0 === 1
-1>>>0 === 0xFFFFFFFF -1>>0 === -1
1.7>>>0 === 1
0x100000002>>>0 === 2
1e21>>>0 === 0xDEA00000 1e21>>0 === -0x21600000
Infinity>>>0 === 0
NaN>>>0 === 0
null>>>0 === 0
'1'>>>0 === 1
'x'>>>0 === 0
Object>>>0 === 0
(*: well, they're defined as behaving like floats. It wouldn't surprise me if some JavaScript engine actually used ints when it could, for performance reasons. But that would be an implementation detail you wouldn't get to take any advantage of.)
The unsigned right shift operator is used in the all the array extra's method implementations of Mozilla, to ensure that the length property is a unsigned 32-bit integer.
The length property of array objects is described in the specification as:
Every Array object has a length property whose value is always a nonnegative integer less than 232.
This operator is the shortest way to achieve it, internally array methods use the ToUint32 operation, but that method is not accessible and exist on the specification for implementation purposes.
The Mozilla array extras implementations try to be ECMAScript 5 compliant, look at the description of the Array.prototype.indexOf method (§ 15.4.4.14):
1. Let O be the result of calling ToObject passing the this value
as the argument.
2. Let lenValue be the result of calling the [[Get]] internal method of O with
the argument "length".
3. Let len be ToUint32(lenValue).
....
As you can see, they just want to reproduce the behavior of the ToUint32 method to comply with the ES5 spec on an ES3 implementation, and as I said before, the unsigned right shift operator is the easiest way.
That is the unsigned right bit shift operator. The difference between this and the signed right bit shift operator, is that the unsigned right bit shift operator (>>>) fills with zeroes from the left, and the signed right bit shift operator (>>) fills with the sign bit, thus preserving the sign of the numerical value when shifted.
Driis has sufficiently explained what the operator is and what it does. Here's the meaning behind it/why it was used:
Shifting any direction by 0 does returns the original number and will cast null to 0. It seems that the example code that you are looking at is using this.length >>> 0 to ensure that len is numeric even if this.length is not defined.
For many people, bitwise operations are unclear (and Douglas Crockford/jslint suggests against using such things). It doesn't mean that its wrong to do, but more favorable and familiar methods exist to make code more readable. A more clear way to ensure that len is 0 is either of the following two methods.
// Cast this.length to a number
var len = +this.length;
or
// Cast this.length to a number, or use 0 if this.length is
// NaN/undefined (evaluates to false)
var len = +this.length || 0;
>>> is the unsigned right shift operator (see p. 76 of the JavaScript 1.5 specification), as opposed to the >>, the signed right shift operator.
>>> changes the results of shifting negative numbers because it does not preserve the sign bit when shifting. The consequences of this is can be understood by example, from an interpretter:
$ 1 >> 0
1
$ 0 >> 0
0
$ -1 >> 0
-1
$ 1 >>> 0
1
$ 0 >>> 0
0
$ -1 >>> 0
4294967295
$(-1 >>> 0).toString(16)
"ffffffff"
$ "cabbage" >>> 0
0
So what is probably intended to be done here is to get the length, or 0 if the length is undefined or not an integer, as per the "cabbage" example above. I think in this case it is safe to assume that this.length will never be < 0. Nevertheless, I would argue that this example is a nasty hack, for two reasons:
The behavior of <<< when using negative numbers, a side-effect probably not intended (or likely to occur) in the example above.
The intention of the code is not obvious, as the existence of this question verifies.
Best practice is probably to use something more readable unless performance is absolutely critical:
isNaN(parseInt(foo)) ? 0 : parseInt(foo)
Two reasons:
The result of >>> is an "integral"
undefined >>> 0 = 0 (since JS will try and coerce the LFS to numeric context, this will work for "foo" >>> 0, etc. as well)
Remember that numbers in JS have an internal-representation of double.
It's just a "quick" way of basic input sanity for length.
However, -1 >>> 0 (oops, likely not a desired length!)
Sample Java Code below explains well:
int x = 64;
System.out.println("x >>> 3 = " + (x >>> 3));
System.out.println("x >> 3 = " + (x >> 3));
System.out.println(Integer.toBinaryString(x >>> 3));
System.out.println(Integer.toBinaryString(x >> 3));
Output is the following:
x >>> 3 = 536870904
x >> 3 = -8
11111111111111111111111111000
11111111111111111111111111111000

Categories

Resources