Why this result "-9 >> 2 = -3" - javascript

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

Related

Trouble figuring out Javascript & operator

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

>>> (Zero-fill right shift) when second oprand is zero

I understand what is Zero-fill right shift and results it yields make perfect sense when second operand is non-zero:
-7 >>> 1
2147483644
Compare with
-7 >> 1
-4
But when second operand is zero:
-7 >> 0
-7 // Looks right!
-7 >>> 0
4294967289 // What? Why?
If I'm shifting zero bits, doesn't it mean I'm not shifting at all? If that's the case, shouldn't it give me back the original number? I would expect -7 >>> 0 === -7
And also
-7 >>> 32
4294967289
Again, by definition, I would expect -7 >>> n === 0 where n >= 32 because all digits become zeros!
Found the internal workings of it in specs.
x >>> 0 will do ToUint32(x)
And
7.1.6 ToUint32 ( argument )
The abstract operation ToUint32 converts argument to one of 232
integer values in the range 0 through 232−1, inclusive. This abstract
operation functions as follows: Let number be ToNumber(argument).
ReturnIfAbrupt(number). If number is NaN, +0, −0, +∞, or −∞, return
+0. Let int be the mathematical value that is the same sign as number and whose magnitude is floor(abs(number)). Let int32bit be int modulo
232. Return int32bit.
Note Let int32bit be int modulo, and
The notation “x modulo y” (y must be finite and nonzero) computes a
value k of the same sign as y (or zero) such that abs(k) < abs(y) and
x−k = q × y for some integer q.
So by above convention, -7 mod 2^32 === 2^32 - 7 === 4294967289

Javascript Date() milliseconds difference not adding up

I've created this JSFiddle to illustrate my question.
It seems that 10 - 00 = 8 in this example.
The simple question: Why does #ha contain 8? Have I misunderstood something?
var a4 = new Date(2012,00,00,00,00,00,0010);
var b4 = new Date(2012,00,00,00,00,00,0000);
var c4 = a4-b4;
var d4 = document.getElementById("ha");
d4.innerHTML=c4;
When an integer literal starts with 0 it is interpreted as an octal literal, not a decimal literal. The literal 0010 has the same value as the literal 8 . Remove the leading zeroes.
using a leading 0 on a number is a signal to the processor that you're using an octal (base 8) number the same way that 0x indicates hex.
0010 - 0 == 010 == 8 in base ten
10 - 0 == 10 == 10 in base ten
0x10 - 0 == 0x10 == 16 in base ten

What does 0x0F mean? And what does this code mean?

I have this code. Please make me understand what does this code actually mean
for(var i = 0; i < input.length; i++)
{
x = input.charCodeAt(i);
output += hex_tab.charAt((x >>> 4) & 0x0F)
+ hex_tab.charAt( x & 0x0F);
}
What is 0x0F? And, >>> Mean?
>>> is the unsigned bitwise right-shift operator. 0x0F is a hexadecimal number which equals 15 in decimal. It represents the lower four bits and translates the the bit-pattern 0000 1111. & is a bitwise AND operation.
(x >>> 4) & 0x0F gives you the upper nibble of a byte. So if you have 6A, you basically end up with 06:
6A = ((0110 1010 >>> 4) & 0x0F) = (0000 0110 & 0x0F) = (0000 0110 & 0000 1111) = 0000 0110 = 06
x & 0x0F gives you the lower nibble of the byte. So if you have 6A, you end up with 0A.
6A = (0110 1010 & 0x0F) = (0110 1010 & 0000 1111) = 0000 1010 = 0A
From what I can tell, it looks like it is summing up the values of the individual nibbles of all characters in a string, perhaps to create a checksum of some sort.
0x0f is a hexadecimal representation of a byte. Specifically, the bit pattern 00001111
It's taking the value of the character, shifting it 4 places to the right (>>> 4, it's an unsigned shift) and then performing a bit-wise AND with the pattern above - eg ignoring the left-most 4 bits resulting in a number 0-15.
Then it adds that number to the original character's right-most 4 bits (the 2nd & 0x0F without a shift), another 0-15 number.
0x0F is a number in hexadecimal. And >>> is the bitwise right-shift operator.

What does the "|" (single pipe) do in JavaScript?

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

Categories