If 1 is 32 bits then 1 << 32 is equal to 0.
If 1 is 64 bits then 1<< 32 is 4294967296.
So where is 1 coming from in JS? is it undefined behaviour?
https://jsfiddle.net/xn2hr7fa/1/
As is the case with many languages, the left shift operator only uses the five least significant bits (treating the shift distance as a 32-bit int). Refer to Step 7 here.
Thus:
1 << 32 === 1 << (32 & 0x1f) which is 1 << 0 === 1
1 << 33 === 1 << (33 & 0x1f) which is 1 << 1 === 2
1 << 34 === 1 << (34 & 0x1f) which is 1 << 2 === 4
and so on.
Related
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
I have been trying to find the answer all morning, so happy to close this question if it is a duplicate. I am tying to get the first 2 digits of a hex number that has 8 digits.
I understand that >> moves x bits to the right. So doing 0b10 >> 1 ends up in 0b01
All works for the last 6 digits.
The last 2 hex numbers:
0x000000FF >> 0 // 255
0b00000000000000000000000011111111 >> 0 == 0b00000000000000000000000011111111 // == 255
The 3th and 4th hex digit from the right:
0x0000ff00 >> 8 // 255
0b00000000000000001111111100000000 >> 8 == 0b00000000000000000000000011111111 // == 255
The 5th and the 6th hex from right:
0x00ff0000 >> 16
0b00000000111111110000000000000000 >> 16 == 0b00000000000000000000000011111111 // == 255
Trying to get the 7th and 8th hex number from the rigth, or the first 2 from the left should moving all bits 24 places to the right:
0xff000000 >> 24
0b11111111000000000000000000000000 >> 24 => Should be 255, but it is -1
How can I get 0b11111111000000000000000000000000 to become 255?
The answer is simple, the >> operator is a signed shift operator, so instead you would simply use an unsigned version >>>:
console.log(0xff000000 >> 24)
console.log(0xff000000 >>> 24)
I saw this in some JS code:
index = [
ascii[0] >> 2,
((ascii[0] & 3) << 4) | ascii[1] >> 4,
((ascii[1] & 15) << 2) | ascii[2] >> 6,
ascii[2] & 63
];
I'd quite like to know what a lot of this means. Specifically ">>", a single pipe "|" and the "&" symbol on the last line?
Much appreciated!
x >> y means to shift the bits of x by y places to the right (<< to the left).
x | y means to compare the bits of x and y, putting a 1 in each bit if either x or y has a 1 in that position.
x & y is the same as |, except that the result is 1 if BOTH x and y have a 1.
Examples:
#left-shifting 1 by 4 bits yields 16
1 << 4 = b00001 << 4 = b10000 = 16
#right-shifting 72 by 3 bits yields 9
72 >> 3 = b1001000 >> 3 = b1001 = 9
#OR-ing
8 | 2 = b1000 | b0010 = b1010 = 10
#AND-ing
6 & 3 = b110 & b011 = b010 = 2
For more information, search Google for "bitwise operators".
>> is a right bitwise shift. It takes the bits and shifts them right n places1. For example, let's examine 35 >> 2:
35 = 100011 shift two places
001000 = 8
And indeed, 35 >> 2 == 8.
| is a bitwise OR. It takes each bit in each operand and ORs them together. You can envision it as a sort of binary addition, but you don't carry when both top and bottom are 1. For example, here's 5 | 3:
5 = 101
3 = 011
| -----
111 = 7
And indeed, 5 | 3 == 7.
Finally, & is a bitwise AND. It takes each bit in each operand, except instead of giving 1 if either one bit OR the other is one, it gives 1 if one bit AND the other are both one. For example, here's 5 & 3:
5 = 101
3 = 011
& -----
001 = 1
Try it out; 5 & 3 == 1.
Some other ones you might want to be aware of are <<, which is a left bitwise shift, and ^, which is an XOR (0 when both bits are the same, 1 if they're different).
1 Actually, it's n modulo 32. 1 >> 32 is 1. Not sure why.
The >> and << operators are a bitwise shift. For example,
11 = 00001011
11 << 3 = 01011000 = 88
It is worth noting that m << n = m * 2^n and m >> n = m / 2^n. This is sometimes used to do very efficient multiplication/division by powers of 2.
The & and | are bitwise and and or respectively.
11 = 00001011
28 = 00011100
11 & 28 = 00001000 = 8
11 = 00001011
28 = 00011100
11 | 28 = 00011111 = 31
While I'm at it, I should mention the ^ operator, which is not used for power, but for bitwise exclusive-or.
11 = 00001011
28 = 00011100
11 ^ 28 = 00010111 = 23
& (Bitwise AND)
| (Bitwise OR)
<< (Left shift)
>> (Sign-propagating right shift)
Examples (from https://developer.mozilla.org/en/JavaScript/Reference/Operators/Bitwise_Operators):
Bitwise and:
9 (base 10) = 00000000000000000000000000001001 (base 2)
14 (base 10) = 00000000000000000000000000001110 (base 2)
--------------------------------
14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
Left shift (9 << 2 shifts bits of 9 in binary, 2 bits to the left):
9 (base 10): 00000000000000000000000000001001 (base 2)
--------------------------------
9 << 2 (base 10): 00000000000000000000000000100100 (base 2) = 36 (base 10)
Looks like bitwise operators to me:
http://web.eecs.umich.edu/~bartlett/jsops.html
Edit: that ascii array was a dead give away... LOL
Running the following JavaScript code shows 63 in both cases:
alert( 0xff >> 2 );
alert( 0xff >>> 2 );
What is the differences between >> and >>>? Their results seem to be equal.
>> is a bitwise operator, which shift the bits to the right. Any bits at the right are lost.
8 = 1000
^-->1
= 0000 = 0
>>> does the similar thing as >>, but it's unsigned, which means that it ranges from 0 to 232-1 instead of +/- 231-1.
To see the result of my first statement in action, let's use the bitwise operator to floor a number:
1.234 >> 0 = 1 // Ok, fraction lost
1.234 >>>0 = 1 // Ok, fraction lost
-1.23 >> 0 = -1 // Ok, fraction lost
-1.23 >>>0 = 4294967295 // (negative numbers are not within the range)
Math.pow(2,31) >> 0 = -2147483648 // 2^31 is out of range
Math.pow(2,31) >>> 0 = 2147483648
So, when the upper boundary of a range is exceeded, the calculation will continue at its lower range, and vice versa (eg <<). The following illustrates shows what happens when you use n = (n + 1) >> 0, and >>> 0, for n starting at the lowest boundary.
// Signed Unsigned
>> >>>
-2147483647 0
-2147483646 1
... ...
2147483646 4294967294
2147483647 4294967295
-2147483647 0
-2147483646 1
It is the Unsigned Right Shift Operator.
A few links:
Shift with zero fill
Shift with sign
I have the following code:
var v = [0xFF, 0xFF];
alert((v[0]<<8) | v[1]);
And it alerts 65535 (the max short value).
How can I treat this byte array as a signed short, and get the signed value of this array.
Assuming the higher bit is the sign:
var sign = v[0] & (1 << 7);
var i = ((v[0] & 0x7F) << 8) | v[1];
if (sign) {
i = -i;
}
http://jsfiddle.net/p4TQw/1/
If you use the Two's complement representation:
var i = (((v[0] << 8) | v[1]) << 16) >> 16);
The 16 bits left shift moves all bits to the left; and the arithmetic 16 bits right shift takes care of the sign while shifting. (Javascript uses 32 bits integers for shift operations.)
http://jsfiddle.net/p4TQw/3/