What does the bitwise shift left accomplish here? [duplicate] - javascript

This question already has answers here:
Why does a shift by 0 truncate the decimal?
(5 answers)
Closed 3 years ago.
https://stackoverflow.com/a/15106541/10757573
In this thread, the solution uses the following code:
var randomProperty = function (obj) {
var keys = Object.keys(obj)
return obj[keys[ keys.length * Math.random() << 0]];
};
In the comments from the answer, one user explained the bitwise shift as:
It's more as a shorthand of parseInt(keys.length * Math.random(), 0)
Can anyone explain how the bitwise shift left 0 is the same as parseInt, or how it works in general, please?
I'm using this syntax, and it works well, but I don't understand what it's doing.

Performing value << 0 in JavaScript has the effect of coercing value into an integer when value is a non-integer. This is needed in this case because Math.random() returns a floating-point number, which cannot be used as an integer indexer (keys is an Array so it's indexed by an integer).
parseInt( /*string:*/ textValue, /*radix:*/ 0 ) does not convert a number to "base 0", instead when radix == 0, the parseInt function will parse textValue as base 10 unless textValue starts with 0x in which case it will parse it as base 16.

The usual idiom for selecting a random array element is
array[Math.floor(array.length * Math.random())]
What this code is doing is using << 0 as a shortcut for Math.floor(). keys.length * Math.random() will be a floating point number. The << operator requires that its operands be integers, so it will automatically convert that float to an integer, and it does this by rounding down, just like Math.floor() does.

Related

JS Bitwise - what are the rules of Math.random() * 2 being interpreted as 0 and 1 for purposes of bitwise Or (|) operation?

Why learning about bind() method on http://javascriptissexy.com/javascript-apply-call-and-bind-methods-are-essential-for-javascript-professionals/, I have come across an interesting calculation which looks like this:
var randomNum = ((Math.random () * 2 | 0) + 1) - 1;
Trying to understand what | sign does, I came across JavaScript Bitwise operators (https://www.w3schools.com/js/js_bitwise.asp).
And I got to know that (Math.random () * 2 | 0) is a bitwise OR operation.
I grasped that Math.random() * 2 sometimes gives value of 0 or 1 in terms of bitwise values (for example, 0.06218657045669751 is interpreted as 1). I wrote a function to check, in which situations the result of Math.random() * 2 calculation is treated as 0 and in which it is treated as 1:
function showNumber() {
console.log(Math.random() * 2);
return Math.random() * 2 | 0;
}
showNumber();
The results did not give me any answer to my questions.
Because if Math.random() * 2 gives 1.5337258727722651 it can as well be interpreted as 1 and 0.
Is this interpretation random by rule or is there any logic behind?
Normally, OR'ing with false (0) doesn't do anything: x or false is equivalent to x. The same goes for bitwise OR with the number 0. The x | 0 construction is just a JavaScript idiom for turning a floating-point number into an integer (truncating).
Because Math.random() * 2 is a number between 0.0 (inclusive) and 2.0 (exclusive), rounding down in this way gives a 50/50 chance of being either 0 or 1.
#Thomas already answered the question of why this returns 0 or 1. However, I would like to emphasise the difference between Math.floor and | 0 (as mentioned in the comments).
In most cases, these would indeed provide the same result and in most cases, Math.floor would be easier to read and understand, especially for beginners.
If your input is from a user or a database, you can't be sure the input is really a number. Math.floor correctly handles string values, but does have a few weird quirks for other kinds of values.
For example: Math.floor(null) returns 0, while Math.floor(undefined) returns NaN. Using the bitwise operator, 0 would be returned in both cases.
Taking it a step further would be to have an object as input. Math.floor({}) returns NaN while a={}; a | 0 still returns 0 and {} | 0 would actually throw a SyntaxError.
A more credible example would be to pass NaN as input. Math.floor would return NaN and the bitwise operator would return 0.
So in short, the bitwise operator always returns a valid 32-bit integer, while Math.floor may also return NaN.

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

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

What's the >>> operator? [duplicate]

This question already has answers here:
What is the JavaScript >>> operator used for? [duplicate]
(2 answers)
Closed 9 years ago.
In filter documentation page in Mozilla website, I saw >>> operator:
var t = Object(this),
len = t.length >>> 0, //here
res, thisp, i, val;
if (typeof fun !== 'function') {
throw new TypeError();
}
Here you can find the complete document: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
What's this operator and what it does?
It's a bit shift operator.
From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators,
a >>> b shifts a in binary representation b bits to the right, discarding bits shifted off, and shifting in zeros from the left.
That doesn't explain why anyone would bother to shift a value zero bits to the right, though. You might as well multiply it by one, or add zero.
As others explained, it is the "bitwise shift with zero" operator.
With positive values this has the same effect as the normal >> operator. With negative values, the most-significant bit is the "sign" bit. Normal shifting will shift the sign bit in (1 for negative values, 0 for positive). >>> has a different effect, because it always shifts in a zero instead of the sign bit:
-2>>1 == -1
-2>>>1 == 2147483647
More on how negative values are represented can be found here.
What all shift operators do is cast the value to a 32-bit integer (at least my Firefox does), so shifting by 0 means that the value will always be within the 32-bit range. Bitwise shift with 0 will also make sure the value is positive:
a = Math.pow(2,32) // overflow in 32-bit integer
a>>0 == 0
b = Math.pow(2,32) - 1 // max 32-bit integer: -1 when signed, 4294967295 when unsigned
b>>0 == -1
b>>>0 == 4294967295 // equal to Math.pow(2,32)-1
Called Bitwise Shift Right with Zero Operator. This operator is just like the >> operator, except that the bits shifted in on the left are always zero.
For example: (A >>> 1) is 1.
http://www.tutorialspoint.com/javascript/javascript_operators.htm
Update:
This explains what bitwise shift operators do: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_shift_operators

JavaScript | operator [duplicate]

This question already has answers here:
Using bitwise OR 0 to floor a number
(7 answers)
Closed 8 years ago.
Anyone able to explain what "|" and the value after does? I know the output for 0 creates sets of 13, the numbers, 3, 2, 1, 0. But what about | 1, or | 2.
var i = 52;
while(i--) {
alert(i/13 | 0);
}
It is the bitwise OR operator. There is both an explanation and an example over at MDC. Since doing bitwise OR with one operand being 0 produces the value of the other operand, in this case it does exactly nothing rounds the result of the division down.
If it were written | 1 what it would do is always print odd numbers (because it would set the 1-bit to on); specifically, it would cause even numbers to be incremented by 1 while leaving odd numbers untouched.
Update: As the commenters correctly state, the bitwise operator causes both operands to be treated as integers, therefore removing any fraction of the division result. I stand corrected.
This is a clever way of accomplishing the same effect as:
Math.floor(i/13);
JavaScript developers seem to be good at these kinds of things :)
In JavaScript, all numbers are floating point. There is no integer type. So even when you do:
var i = 1;
i is really the floating point number 1.0. So if you just did i/13, you'd end up with a fractional portion of it, and the output would be 3.846... for example.
When using the bitwise or operator in JavaScript, the runtime has to convert the operands to 32 bit integers before it can proceed. Doing this chops away the fractional part, leaving you with just an integer left behind. Bitwise or of zero is a no op (well, a no op in a language that has true integers) but has the side effect of flooring in JavaScript.
It's a bitwise operator. Specifically the OR Bitwise Operator.
What it basically does is use your var as an array of bits and each corresponding bit is with eachother. The result is 1 if any of them is 1. And 0 if both are 0.
Example:
24 = 11000
10 = 1010
The two aren't of equal length so we pad with 0's
24 = 11000
10 = 01010
26 = 11010
24 | 10 = 26
Best way to learn this is to readup on it.
That is the bitwise OR. In evaluating the expression, the LHS is truncated to an integer and returned, so | is effecively the same as Math.floor().

Categories

Resources