In JS, we have the following situation:
<< operator:
3 << 1 // 6
5 << 1 // 10
7 << 1 // 14
-3 << 1 // -6
-5 << 1 // -10
-7 << 1 // -14
>> operator:
3 >> 1 // 1
5 >> 1 // 2
7 >> 1 // 3
-3 >> 1 // -2
-5 >> 1 // -3
-7 >> 1 // -4
As you can see, for the << operator, and for values less than 2**32, we have abs(X << Y) === abs(-X << Y).
Why doesn't this keep true for the >> operator?
Because you are rotating the binary representation of those numbers. And the negative numbers are stored as 2's complement binary
So (using just 8-bits for illustration purposes):
-3 = 11111101
Which if you rotate with >> which is sign propagating you will get:
11111110 = -2
Because the sign propagating shift copies the sign bit to the left-most bit.
With the positive numbers it's easier:
3 = 00000011
After shifting with >> (since it's positive, you are shifting in zeros)
00000001 = 1
It's because minus has greater precedence than shift operator.
So, -3 >> 1 will run as (-3) >> (1) but not as -(3 >> 1).
Related
So I am new to Javascript, in my first Intro to Javascript class. I just found what the & operator does and came across this definition:
The & operator returns a one in each bit position for which the corresponding bits of both operands are ones.
I was also able to find descriptions of == and === on this website on a question that has been previously answered. On this link here: Wikipedia Bitwise_operation#AND
It explains that 1 & 1 is the same as 1 x 1, simple multiplication. So my question is then why is 10 & 5 == 0 and 10 & 6 == 2
Wouldn't it be 10 & 5 == 50 and 10 & 6 == 60?
What am I failing to understand?
It's only the binary bits in each position (the 1s and 0s) that are multiplied.
For example, with 10 & 5:
10 = 1010 in binary
5 = 0101 in binary
Now multiply each digit against the other digit in the same position:
(1 x 0) (0 x 1) (1 x 0) (0 x 1)
= 0000
= 0 in decimal
console.log(10 & 5)
With 10 & 6:
10 = 1010 in binary
6 = 0110 in binary
Now multiply each digit against the other digit in the same position:
(1 x 0) (0 x 1) (1 x 1) (0 x 0)
= 0010
= 2 in decimal
console.log(10 & 6)
It’s equivalent to multiplication per bit.
0 & 0 === 0
0 & 1 === 0
1 & 1 === 1
So your example of 10 & 5 is:
1010
& 0101
= 0000
If you switch from base 10 to base 2, which is required when comparing numbers bitwise, then it is clearer :
10 & 5 becomes 1010 & 0101 which equals 0000 in base 2, 0 in base 10
10 & 6 becomes 1010 & 0110 which equals 0010 in base 2, 2 in base 10
Hope this helps!
So 10 should be something like this 1010
and 5 should be something like this 0101
Now, if you find & or And for both of them, You should get something like 0000 which is zero
Similarly for 6, it should be 0110
which should give & or And for both of them as 0010 which happens to be 2
Note: for And we have the following rule
0 & 0 === 0
0 & 1 === 0
1 & 1 === 1
Try going through w3c article: https://www.w3schools.com/jsref/jsref_operators.asp
console.log(0.5 | 0); // 0
console.log(-1 | 0); // -1
console.log(1 | 0); // 1
Why does 0.5 | 0 return zero, but any integer (including negative) returns the input integer? What does the single pipe ("|") do?
This is a bitwise or.
Since bitwise operations only make sense on integers, 0.5 is truncated.
x | 0 is x, if x is an integer.
Bit comparison is so simple it's almost incomprehensible ;) Check out this "nybble"
8 4 2 1
-------
0 1 1 0 = 6 (4 + 2)
1 0 1 0 = 10 (8 + 2)
=======
1 1 1 0 = 14 (8 + 4 + 2)
Bitwise ORing 6 and 10 will give you 14:
alert(6 | 10); // should show 14
Terribly confusing!
A single pipe is a bit-wise OR.
Performs the OR operation on each pair
of bits. a OR b yields 1 if either a
or b is 1.
JavaScript truncates any non-integer numbers in bitwise operations, so its computed as 0|0, which is 0.
This example will help you.
var testPipe = function(input) {
console.log('input => ' + input);
console.log('single pipe | => ' + (input | 'fallback'));
console.log('double pipe || => ' + (input || 'fallback'));
console.log('-------------------------');
};
testPipe();
testPipe('something');
testPipe(50);
testPipe(0);
testPipe(-1);
testPipe(true);
testPipe(false);
This is a Bitwsie OR (|).
The operands are converted to 32-bit integers and expressed by a series of bits (zeroes and ones). Numbers with more than 32 bits get their most significant bits discarded.
So, in our case decimal number is converted to interger 0.5 to 0.
= 0.5 | 0
= 0 | 0
= 0
What is the meaning of this line of code
n = (n<<1) | ((d>=0.0004)?1:0);
Trying to understand code from here in function sigOff()
http://www.espruino.com/Remote+Control+Sockets
This snippet seems to use the bitwise OR (|) and left shift (<<) operators:
Bitwise OR: a | b;
Returns a one in each bit position for which the corresponding bits of either or both operands are ones.
Left shift: a << b;
Shifts a in binary representation b (< 32) bits to the left, shifting in zeros from the right.
The left shift by 1 (<< 1) basically doubles the value of n.
Then, the or (|) basically "adds" 1 to the result to make it uneven, if d >= 0.0004.
If d < 0.0004, the result from the left shift isn't changed.
So, for n == 3 and d == 0.0004, this happens:
n << 1 // 6
(d>=0.0004)?1:0 // 1
6 | 1 // 7
For n == 5 and d == 0.0002, this happens:
n << 1 // 10
(d>=0.0004)?1:0 // 0
10 | 0 // 10
Why
9 >> 2 = 2
and
-9 >> 2 = -3
?
I mean, why not -2.
From the bitwise operators page on MDN -
"The operands of all bitwise operators are converted to signed 32-bit integers in big-endian order and in two's complement format. Big-endian order means that the most significant bit (the bit position with the greatest value) is the left-most bit if the 32 bits are arranged in a horizontal line. Two's complement format means that a number's negative counterpart (e.g. 5 vs. -5) is all the number's bits inverted (bitwise NOT of the number, a.k.a. one's complement of the number) plus one."
1001 (9) >> 2 = 10 (2)
2's compliment 9 to get -9 and do the same:
0111 (-9) >> 2 = 01
2's compliment the result and you get 11 or 3, so the answer is -3
-1 = 11111111
-2 = 11111110
-3 = 11111101
-4 = 11111100
..
-8 = 11111000
-9 = 11110111
thus
-9 >> 2 = -3
console.log(0.5 | 0); // 0
console.log(-1 | 0); // -1
console.log(1 | 0); // 1
Why does 0.5 | 0 return zero, but any integer (including negative) returns the input integer? What does the single pipe ("|") do?
This is a bitwise or.
Since bitwise operations only make sense on integers, 0.5 is truncated.
x | 0 is x, if x is an integer.
Bit comparison is so simple it's almost incomprehensible ;) Check out this "nybble"
8 4 2 1
-------
0 1 1 0 = 6 (4 + 2)
1 0 1 0 = 10 (8 + 2)
=======
1 1 1 0 = 14 (8 + 4 + 2)
Bitwise ORing 6 and 10 will give you 14:
alert(6 | 10); // should show 14
Terribly confusing!
A single pipe is a bit-wise OR.
Performs the OR operation on each pair
of bits. a OR b yields 1 if either a
or b is 1.
JavaScript truncates any non-integer numbers in bitwise operations, so its computed as 0|0, which is 0.
This example will help you.
var testPipe = function(input) {
console.log('input => ' + input);
console.log('single pipe | => ' + (input | 'fallback'));
console.log('double pipe || => ' + (input || 'fallback'));
console.log('-------------------------');
};
testPipe();
testPipe('something');
testPipe(50);
testPipe(0);
testPipe(-1);
testPipe(true);
testPipe(false);
This is a Bitwsie OR (|).
The operands are converted to 32-bit integers and expressed by a series of bits (zeroes and ones). Numbers with more than 32 bits get their most significant bits discarded.
So, in our case decimal number is converted to interger 0.5 to 0.
= 0.5 | 0
= 0 | 0
= 0