Strange javascript operator: expr >>> 0 [duplicate] - javascript

This question already has answers here:
What is the JavaScript >>> operator and how do you use it?
(7 answers)
Closed 7 years ago.
the following function is designed to implement the indexOf property in IE. If you've ever had to do this, I'm sure you've seen it before.
if (!Array.prototype.indexOf){
Array.prototype.indexOf = function(elt, from){
var len = this.length >>> 0;
var from = Number(arguments[1]) || 0;
from = (from < 0)
? Math.ceil(from)
: Math.floor(from);
if (from < 0)
from += len;
for (; from < len; from++){
if (from in this &&
this[from] === elt)
return from;
}
return -1;
};
}
I'm wondering if it's common to use three greater than signs as the author has done in the initial length check?
var len = this.length >>> 0
Doing this in a console simply returns the length of the object I pass to it, not true or false, which left me pondering the purpose of the syntax. Is this some high-level JavaScript Ninja technique that I don't know about? If so, please enlighten me!

>>> is the Zero-fill right shift operator. The >>> 0 is an abuse of the operator to convert any numeric expression to an "integer" or non-numeric expression to zero. Here is what it does:
This operator shifts the first operand the specified number of bits to
the right. Excess bits shifted off to the right are discarded. Zero
bits are shifted in from the left. The sign bit becomes 0, so the
result is always positive.
Here is an explanation of the convert-to-integer behavior which applies to all bitwise operations:
Bitwise operators treat their operands as a sequence of 32 bits (zeros
and ones), rather than as decimal, hexadecimal, or octal numbers.
[...] Bitwise operators perform their operations on such binary
representations, but they return standard JavaScript numerical values.
Together, these statements assert that expr >>> 0 will always return a positive number as follows:
expr is cast to a 32-bit integer for bitwise operation
>>> 0 has no effect (no bits are shifted)
The result is converted to a Number
Here are a few expressions and their outcome:
1 >>> 0 // 1 -- Number cast to 32-bit integer then back to Number
"1" >>> 0 // 1 -- String cast to 32-bit integer then back to Number
undefined >>> 0 // 0 -- failed cast yields zero
Other interesting cases:
1.1 >>> 0 // 1 -- decimal portion gets it
-1 >>> 0 // 4294967295 -- -1 = 0xFFFFFFFF
// Number(0xFFFFFFFF) = 4294967295
"A" >>> 0 // 0 -- cast failed
"1e2" >>> 0 // 100 -- 1x10^2 is 100
"1e10" >>> 0 // 1410065408 -- 1x10^10 is 10000000000
// 10000000000 is 0x00000002540BE400
// 32 bits of that number is 0x540BE400
// Number(0x540BE400) is 1410065408
Note: you will notice that none of them return NaN.

Source: LINK
This is the zero-fill right shift
operator which shifts the binary
representation of the first operand to
the right by the number of places
specified by the second operand. Bits
shifted off to the right are discarded
and zeroes are added on to the left.
With a positive number you would get
the same result as with the
sign-propagating right shift operator,
but negative numbers lose their sign
becoming positive as in the next
example, which (assuming 'a' to be
-13) would return 1073741820:
Code:
result = a >>> b;

The >>> (right-shift) binary operator is simply shifting the right-most bits of a number a specified number of times, and padding with zeroes to the left.
Note: In the following examples, the number in braces after a number signals what base it's in. 2 is for binary, 10 for decimal.
For example, 4 >>> 1 would do:
4(10) = 100(2)
4(10) >>> 1(10) = 010(2) = 2(10)
shift once to the right
Other examples:
4(10) >>> 2(10) = 100(2) >>> 2(10) = 001(2) = 1(10)
10(10) >>> 4(10) = 1010(2) >>> 4(10) = 0000(2) = 0(10)
15(10) >>> 1(10) = 1111(2) >>> 1(10) = 0111(2) = 7
The way I remember it is to move the necessary amount of bits to the right, and then write the number. Like, in the last example, I simply moved everything to the right once, so the result is 0111.
Shifting 0 times does...nothing. No idea why it's there.

Behold the zero-fill right-shift operator.
https://developer.mozilla.org/en/JavaScript/Reference/Operators/Bitwise_Operators

Related

How do Bitwise Operators work?

So I was going through some problems at codewars.com and I came across a problem about basic encryption (https://www.codewars.com/kata/basic-encryption/javascript). The goal is to get a string value and shift it x values to the right on the ASCII chart.
here was my initial solution:
function encrypt(text, rule) {
let res = ''
for(let i = 0; i<text.length; i++) {
res += (String.fromCharCode(text.charCodeAt(i)+rule))
}
return res
};
However, it didn't pass all of the tests, so I looked at the solutions and this is what got me to pass the tests:
function encrypt(text, rule) {
let res = ''
for(let i = 0; i<text.length; i++) {
res += (String.fromCharCode(text.charCodeAt(i)+rule & 255))
}
return res
};
All because of adding that & 255, Could someone explain to me what has really changed by adding that to make my code valid?
As somebody said above, your valid range of characters is from 0 to 255. There are many ways to valid this condition but bitwise and looks like shortest one.
Bitwise AND returns a one in each bit position for which the corresponding bits of both operands are ones.
For example:
1111 & 0000 would return 0000
1111 & 0001 would return 0001
1111 & 0010 would return 0010
1111 & 0100 would return 0100
But, as you can read in the docs:
Bitwise operators perform their operations on such binary representations, but they return standard JavaScript numerical values.
If you use this operator on integer you would get integer instead of binary.
In your case, using number & 255 makes you sure that end value would be in range from 0 to 255.
You can read more about bitwise operators there.

I don't understand what is happening with this XOR

I am working on this problem.
"Given an array, find the int that appears an odd number of times.
There will always be only one integer that appears an odd number of times."
I came up with this solution online:
function findOdd(A) {
var n = 0;
for(var i = 0; i < A.length; i++){
n = n^A[i];
}
return n;
}
This works but I am not sure why and i was hoping someone could explain it to me. I just don't understand the line:
n = n^A[i];
Could you please tell me what it is doing in this instance?
Xoring any number with itself will result in 0. If you know that there's only one number that appears an odd number of times, the others will cancel themselves out by self-xoring, and the answer will be the remaining number that appears an odd number of times.
XOR of two same numbers is always zero. That is,
A^A=0
So, if you XOR a particular number with itself repeatedly for even number of times, the result will be zero.
Here, initially the value of n is zero. The number that will be XOR-ed even number of times, will result zero. And the number that is present odd number of times, say 2m+1number of times, will result in zero for 2m occurrences, and that same number for the final one occurrence.
This is how this solution works.
^ is an exor bit wise operator . so when you do
1 ^ 1 is 0
0 ^ 1 is 1
1 ^ 0 is 1
0 ^ 0 is 0
so to find the odd number of 1's the following code does is
initially result is arr[0] is 1 .
so in the arrary 0^ 0 becomes 0 and 2 ^ 2 becomes 0 and there are 3 1's so 1^1 gets 0 and with 0 ^1 we are leftout with the number which repeats odd nubmer of times
var arr=[1,1,1,0,0,2,2];
var result=arr[0];
for(var i=1;i<arr.length;i++)
result=result ^ arr[i];
console.log(result);
Hope it helps
Bitwise operators work on 32 bits numbers. Any numeric operand in the operation is converted into a 32 bit number. The result is converted back to a JavaScript number. ^ is a bitwise XOR javascript operator.
Bitwise XOR Operator returns a one in each bit position for which the corresponding bits of either but not both operands are ones.
a XOR b yields 1 if a and b are different. The truth table for the XOR operation is:
a b a XOR b
0 0 0
0 1 1
1 0 1
1 1 0
Explanation for expression n = n^A[i];
let A = [1,2,3,4,5]
for n=0, i=0 => 0 ^ A[0] => 0 ^ 1 => converted to binary 0000 ^ 0001 results to 0001 which is equal to 1
for n=1, i=1 => 1 ^ A[1] => 1 ^ 1 => converted to binary 1111 ^ 0010 results to 1101 which is equal to 13
and so on... Hope this solution helps you to understand the above expression and clear your all doubts.

& 1 JavaScript. How does it work? Clever or good? [duplicate]

This question already has answers here:
Is there a & logical operator in Javascript
(8 answers)
Closed 6 years ago.
I'm looking over the solutions for a CodeWars problem (IQ Test) in which you're given a string of numbers and all the numbers but 1 are either even or odd. You need to return the index plus 1 of the position of the number that's not like the rest of the numbers.
I'm confused about the line that says & 1 in the solution posted below. The code doesn't work w/ && or w/ the & 1 taken away.
function iqTest(numbers){
numbers = numbers.split(' ')
var evens = []
var odds = []
for (var i = 0; i < numbers.length; i++) {
if (numbers[i] & 1) { //PLEASE EXPLAIN THIS LINE!
odds.push(i + 1)
} else {
evens.push(i + 1)
}
}
return evens.length === 1 ? evens[0] : odds[0]
}
Also, would you consider using & 1 to be best practice or is it just "clever" code?
The single & is a 'bitwise' operator. This specific operator (&) is the bitwise AND operator - which returns a one in each bit position for which the corresponding bits of both operands are ones.
The way it's being used here is to test if numbers[i] is an even or odd number. As i loops from 0 to numbers.length, for the first iteration the if statement evaluates 0 & 1 which evaluates to 0, or false. On the next iteration of the loop, the statement will be 1 & 1, which evaluates to 1, or true.
The result - when numbers[i] & 1 evaluates to 0, or false, then numbers[i] is pushed to the odd array. If numbers[i] & 1 evaluates to 1, or true, then numbers[i] is pushed to the even array.
An alternative to the & operator to test for even and odd is to use the modulo operator. numbers[i] % 2 results in the same output. That is, 1 % 2 results in 1, or true as will any odd number, because an odd number divided by 2 results in a remainder of 1. And any even number, like 2 % 2 results in 0 or false because an even number divided by 2 results in a remainder of 0.
As for your second question, is it 'clever or good?'. It's definitely clever. Whether it's good depends on who you ask and what your goal is. Many would say its less logical and harder to read than using num % 2.
Binary number is 0 and 1 and each of them is called bit.
Single & is add operation and it works bitwise.
like
1 = 01
2 = 10
3 = 11
4 = 100
You can see that every last bit of odd number is 1 and even number is 0.
In add operation
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
So only odd number will return 1 and even number will return 0 and in programming only 0 consider falsy.
If we wanna to check 5 is a odd or even
5 = 101
and perform and(&) operation with 1
101
& 001
-----
001
and value of binary 001 is 1 in 10 base number
So it'll perform easy odd even process.

What does this symbol mean "&="? [duplicate]

This question already has answers here:
What do these JavaScript bitwise operators do?
(3 answers)
Closed 6 years ago.
function ArithGeo(arr) {
var diff = arr[1]-arr[0];
var ratio = arr[1]/arr[0];
var allRatioAreGood = true;
var allDiffAreGood = true;
for(var i = 2;i<arr.length;i++){
// console.log(arr[i]-arr[i-1] == diff);
allRatioAreGood &= (arr[i]/arr[i-1] == ratio);
allDiffAreGood &= (arr[i]-arr[i-1] == diff);
}
// code goes here
if (allRatioAreGood){
return "Geometric"
}else if (allDiffAreGood){
return "Arithmetic";
}else {
return -1
}
}
console.log(ArithGeo([2, 4, 6, 7 , 8 ,10]));
what does '&=' mean when we used it in the for loop? and how does it work? can someone explain please?
also, how does those two lines work?
allRatioAreGood &= (arr[i]/arr[i-1] == ratio);
allDiffAreGood &= (arr[i]-arr[i-1] == diff);
Can anyone explain please ?
It is the bitwise AND assignment.
In your code example, let's take a look at the first one:
allRatioAreGood &= (arr[i]/arr[i-1] == ratio);
the values arr[i] and arr[i-1] are divided by each other (producing a ratio), and that ratio is tested for equality (using ==), producing a true or false value.
That value is then bitwise AND-ed to the existing value of allRatioAreGood, which means that if the previous value for allRatioAreGood was false (binary 0), then all future values for allRatioAreGood would also result in false (because of the AND operation, 0 & 1 = 0).
The result of this is that allRatioAreGood and allDiffAreGood figures out if all of the values in that array pass that test for equality, that is, if all the values have that "good ratio" or "good difference".
However, in this particular example, the comparator is checking for equality between a ratio and the result of a division, meaning that because the result of a division operation is a floating point number, no other number would be equal to it when testing with ==. To test for "close enough equals", an epsilon needs to be used. See this other SO answer for more info: What's wrong with using == to compare floats in Java? (don't worry that this is Java vs. JavaScript, the concept is the same). Additionally, this gets even more complicated because in Javascript, if the result of ratio or the division operation is NaN or Infinity, you will always get false when comparing the two numbers.
From the docs:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators
Bitwise AND assignment
The bitwise AND assignment operator uses the binary representation of both operands, does a bitwise AND operation on them and assigns the result to the variable. See the bitwise AND operator for more details.
Syntax
Operator: x &= y Meaning: x = x & y
Example
var bar = 5;
// 5: 00000000000000000000000000000101
// 2: 00000000000000000000000000000010
bar &= 2; // 0
a &= b;
is the same as saying:
a = a & b;
So why use this form? Maybe you have a more complex expression, and want to make is clear that a and a are the same lvalue:
obj.array[index].bits = obj.array[index].bits & mask;
versus:
obj.array[index].bits &= mask;
Its a bitwise operator:
result = expression1 & expression2
a &= b; is equivalent to a = a & b;
MDN Docs on bitwise operators
Bitwise AND assignment, pretty much if you have 5 & 3, the use of bitwise converts the numbers to base 2, which is 00101 & 00011 (many more 0's in front) and get 1 because the one's digit's are both 1 (true)
Generally, && is a multiplication, where || is addition, same goes for bitwise, 1 & 1 is 1 * 1 and 1 | 1 is 1 + 1 which is truthy (even though it's still considered a 1..)

Javascript: Comparing two float values [duplicate]

This question already has answers here:
Javascript float comparison
(2 answers)
Closed 6 months ago.
I have this JavaScript function:
Contrl.prototype.EvaluateStatement = function(acVal, cfVal) {
var cv = parseFloat(cfVal).toFixed(2);
var av = parseFloat(acVal).toFixed(2);
if( av < cv) // do some thing
}
When i compare float numbers av=7.00 and cv=12.00 the result of 7.00<12.00 is false!
Any ideas why?
toFixed returns a string, and you are comparing the two resulting strings. Lexically, the 1 in 12 comes before the 7 so 12 < 7.
I guess you want to compare something like:
(Math.round(parseFloat(acVal)*100)/100)
which rounds to two decimals
Compare float numbers with precision:
var precision = 0.001;
if (Math.abs(n1 - n2) <= precision) {
// equal
}
else {
// not equal
}
UPD:
Or, if one of the numbers is precise, compare precision with the relative error
var absoluteError = (Math.abs(nApprox - nExact)),
relativeError = absoluteError / nExact;
return (relativeError <= precision);
The Math.fround() function returns the nearest 32-bit single precision float representation of a Number.
And therefore is one of the best choices to compare 2 floats.
if (Math.fround(1.5) < Math.fround(1.6)) {
console.log('yes')
} else {
console.log('no')
}
>>> yes
// More examples:
console.log(Math.fround(0.9) < Math.fround(1)); >>> true
console.log(Math.fround(1.5) < Math.fround(1.6)); >>> true
console.log(Math.fround(0.005) < Math.fround(0.00006)); >>> false
console.log(Math.fround(0.00000000009) < Math.fround(0.0000000000000009)); >>> false
Comparing floats using short notation, also accepts floats as strings and integers:
var floatOne = 2, floatTwo = '1.456';
Math.floor(floatOne*100) > Math.floor(floatTwo*100)
(!) Note: Comparison happens using integers. What actually happens behind the scenes: 200 > 145
Extend 100 with zero's for more decimal precision. For example use 1000 for 3 decimals precision.
Test:
var floatOne = 2, floatTwo = '1.456';
console.log(Math.floor(floatOne*100), '>', Math.floor(floatTwo*100), '=', Math.floor(floatOne*100) > Math.floor(floatTwo*100));
Comparing of float values is tricky due to long "post dot" tail of the float value stored in the memory. The simplest (and in fact the best) way is: to multiply values, for reducing known amount of post dot digits to zero, and then round the value (to rid of the tail).
Obviously both compared values must be multiplied by the same rate.
F.i.: 1,234 * 1000 gives 1234 - which can be compared very easily. 5,67 can be multiplied by 100, as for reducing the float comparing problem in general, but then it couldn't be compared to the first value (1,234 vel 1234). So in this example it need to be multiplied by 1000.
Then the comparition code could look like (in meta code):
var v1 = 1.234;
var v2 = 5.67;
if (Math.round(v1*1000) < Math.round(v2*1000)) ....

Categories

Resources