alert(15^2) - behaves as alert(15-2), alerts 13
alert(15^10) - behaves as alert(15-10), alerts 5
So it subtracts second number from the first, if the second number is smaller.
But if the second number is larger, for example
alert(15^16), it sums them, behaves as alert(15+16) and alerts 31.
alert(15^3^4) behaves as alert(15-3-4), so it alerts 8.
While
alert(15^3^2) behaves as alert(15-3+2), so it alerts 14.
Can anyone explain me this behavior?
It is called XOR. For each bit on each number it outputs a 1 if both are different.
1 XOR 0 = 1
0 XOR 1 = 1
1 XOR 1 = 0
0 XOR 0 = 0
So when you have the operation 15^2 you are doing:
1111 XOR
0010
----
1101
Which looks like a substraction, but for those special cases only.
As with the cases on multiple times, for example 15^3^4 = (15^3)^4 so you first calculate 15^3 and then the result with 4:
1111 XOR (15)
0011 (3)
----
1100 (12)
and then:
1100 XOR (12)
0100 (4)
----
1000 (8)
Therefore, 15^3^4 = 8.
That is a bitwise XOR operation you are doing, not powers.
According to MDN:
Returns a one in each bit position for which the corresponding bits of either but not both operands are ones.
In javascript, you can use Math.pow to do the math operation.
So
alert(Math.pow(15, 2))
Shows a messagebox with the value 225.
Related
This question already has answers here:
What's the difference between ( | ) and ( || )?
(7 answers)
Closed 4 years ago.
For a while, I have used "||" as the "or" indicator. One day, I was debugging some things in a console, and I accidentally put a single | instead of two. It still worked as expected.
console.log(0||1); // 1
console.log(0|1); // 1
Is there any difference? Here, there evidently isn't, but there might be some hidden difference that I don't know about. I apologize if this is a duplicate, but I assure you I have looked for the answer beforehand.
That is called a bitwise OR, meaning it ORs the individual bits that compose a value based on binary rules.
a b a OR b
0 0 0
0 1 1
1 0 1
1 1 1
For your example, 0 in binary is just 0000, and 1 in binary is 0001.
Thus 0|1 is:
0000 | 0001
Which, when we apply the table above between each binary digit of the two numbers:
0 or 0 = 0
0 or 0 = 0
0 or 0 = 0
0 or 1 = 1
give us 0001, which when converted to decimal becomes 1.
The way || (logical OR) behaves is using coercion rules which returns the first truthy item (or just the last item) in a sequence of ||.
Since 0 is falsy, 0 || 1, will return 1.
Just because the answers happen to be the same in these two situations, does not mean that the operations always produce equal results.
For instance:
2|3 === 3
2||3 === 2
| is a bitwise OR.
Performs the OR operation on each pair of bits. a OR b yields 1 if either a or b is 1
|| is a logical OR.
In your example, 0|1 will evaluate to 1, because ... 0000 | ... 0001 evaluates to ... 0001.
0||1 will evaluate to 1 because 0 is falsy so it'll return the right operand 1
A thing which I noticed in Javascript -
a << -1
Returns 0 when a = even.
Returns -2147483648 when a = odd.
Similarly, different values are returned when -1 is changed to some other -ve number.
Can someone explain what bit operations are taking place under the hood ? Or is the behavior undefined ?
Thanks
EDIT
Also shouldn't Zero-fill right shift i.e. -2 >>> 1 return 7 ?
-2 = 1110. After, right shift with zero-fill, it should give 0111 = 7
but
a = -2; console.log(a >>> 1);
returns
2147483647
I too wondered about this which is how I landed here. I’ve done a little research and figured out the behavior. Essentially JavaScript treats the operand and shift value as sequences of bits rather than as numbers. It works with 32 bit integers (floats get truncated) and the maximum shift is 32 bits. If we shift by a number greater than 32, all the bits would shift out, resulting in zero. To ensure the shift is less than or equal to 32, JavaScript truncates the 5 least significant bits [a << (b&0x1F)] or possibly with the modulus method [a << (b%32)] which yields the same result.
With that out of the way, think of the negative number you are shifting by as a sequence of bits, not a negative number (i.e. -1). In this case b = -1 = 0xFFFFFFFF. Since this number is larger than 32, it is truncated 0xFFFFFFFF & 0x1F = 31 or 0xFFFFFFFF % 32 = 31.
So in your example “a" gets shifted all the way from the least significant bit to the most significant bit (the sign bit). Therefor the result of the shift is either 0x00000000 or (0x80000000 = -2147483648) depending on whether the operand had the 1 bit set (odd or even).
Got the answer to the second part of my question i.e. -2 >>> 1 = 7.
Javascript always deals with 32 bits. So when I do -2 >>> 1, what really happens under the hood is -
11111111111111111111111111111110 >>> 1 which gives 01111111111111111111111111111111 = (2147483647)base10
The LeftShift operator adds zeros to the right of the binary representation of a number, shifting the bits to the left. Only the 5 least significant digits of the additive expression are used. So:
var x = 5 // 101
alert( x << 1 ); // 1010 = 10
alert( x << 2 ); // 10100 = 20
alert( x << 3 ); // 101000 = 40
alert( x << 4 ); // 1010000 = 80
alert( x << 64 ); // 101 = 5
The last expression returns 5 as shift only uses the last 5 bits of the the additive expression, which is 1000000 so only the 00000 part is used.
A questions that stumped me on this JavaScript test was that ~null evaluates to -1.
Why does ~null evaluate to -1?
That's because ~ is a numeric operator, so it casts null to 0 first:
> ~0
-1
It would be equivalent to this expression:
~(+null)
Likewise:
> ~[]
-1
> ~{}
-1
First of all, ~ is a bitwise NOT operator. That means it flips all the bits in the number representation. 0010 1010 becomes 1101 0101.
As a consequence of computers using 2's complement for storing numbers, this equality holds:
~number == -number - 1
As can be shown from my previous example:
0010 1010 (this represents number 42)
1101 0101 (this represents number -43)
Now, because ~ is an operator that operates on numbers, its argument gets cast to a number first. Since null gets cast to a 0, you get -1 as a result (according the above equation).
In Javascript when I do this
var num = 1;
~ num == -2
why does ~num not equal 0
in binary 1 is stored as 1 ... thus not 1 should be 0
or it is stored like 0001 thus not 0001 would be 1110
I think I am missing something... can someone clear this up
Look up Two's complement for signed binary numbers
Lets assume that a javascript Number is 8 bits wide (which its not):
then
1 = 0000 0001b
and
~1 = 1111 1110b
Which is the binary representation of -2
0000 0010b = 2
0000 0001b = 1
0000 0000b = 0
1111 1111b = -1
1111 1110b = -2
~ toggles the bits of the operand so
00000001
becomes
11111110
which is -2
Note: In javascript, the numbers are 32-bit, but I shortened it to illustrate the point.
From the documentation:
Bitwise NOTing any number x yields -(x + 1). For example, ~5 yields -6.
The reason for this is that using a bitwise NOT reverses all the bits of a value. If you are storing the value of 1 in a signed 8-bit integer, you're storing the binary value 00000001. If you apply a bitwise NOT, you get 11111110, which for a signed 8-bit integer is the binary value for -2.
This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
What do these operators do?
>> in javascript
Can somebody please explain the bitwise operator >> 1?
example:
65 >> 1 = 32
and also when >> 0
what does it achieve in this example:
var size = (Math.random() * 100 >> 0) + 20;
var size = (Math.random() * 100 >> 0) + 20;
>> 0 in the above example is used to eliminate the fractional portion, as follows:
Math.random() returns a number between 0 and 0.99999999...
This number multiplied by 100 gives you another number between 0 and 99.999999...
This number is right shifted 0 times. The number is implicitly cast to an integer for the shift operation; right shifting 0 times does not have any effect on the value of the resulting integer. You thus end up with an integer between 0 and 99. Note that you could have used the Math.floor() function instead of >> 0.
Add 20 to the integer, the result is an integer between 20 and 119.
Bitwise operator >> means shift right.
It moves the binary value to the right (and removes the right-most bit).
65 >> 1 in binary is:
1000001 >> 1 = 100000 = 32
It effectively divides the number into 2 and drops the remainder.
The operator '>>' shifts the contents of a variable right by 1 bit. This results, effectively, in integer division of that value by 2 as you show in your example:
65 >> 1 = 32
Let's say that a variable is always 32 bits long. The example then says:
65 decimal >> 1 = 32 or, in hex, 0x000041 >> 1 = 0x00000020
More generally: the operator '>>' divides its operand, as a 32-bit integer, by the power of 2 whose value is the shift length. Thus:
129 decimal >> 1 = 64 or 0x000081 >> 1 = 0x000040
129 decimal >> 2 = 32 or 0x000081 >> 2 = 0x000020
129 decimal >> 5 = 2 or 0x000081 >> 5 = 0x000002
and
129 decimal >> 8 = 0 or: 0x000081 >> 8 = 0x000000
The operator '<<' multiplies its operand, as you'd expect.
I don't know how Math.random( ) operates, but I'm willing to bet that the shift of its floating-point returned value right by 0 turns that number into an integer, because shifting left and right has arithmetic meaning only when the operand is an integer.
The bitwise shift operator shifts each bit of the input x bits to the right (>>) or to the left (<<).
65 is 1000001, thus 65 >> 1 = 0100000, which is 32.
EDIT
Here are some useful links:
http://en.wikipedia.org/wiki/Bitwise_operation
http://javascript.about.com/library/blbitop.htm
http://www.java2s.com/Tutorial/JavaScript/0040__Operators/ShiftLeft.htm
>> X takes the binary number and moves all the digits right by X places.
In your example, you use 65, which is 01000001 in binary. If you shift that right by one, the first space (on the left) gets filled in with a 0, and the last digit 'falls off the end'. Giving 00100000, which is the binary representation for 32.
>> 0, therefore shifts the number 0 spaces to the right, and does nothing.
'<< X', does the same, but shifts the number to the left.
These can be compared to multiplying by 2^X (Left-shift) or divinding by 2^X (right-shift), but it should be noted that a binary shift is much faster than a division operation.
You can understand why the output is 32 from rsplak's post. >> is the Right Bit Shift operator and using it as >> 1 will cause every bit to be shifted one place to the right. This means, if the rightmost bit was 1, it would get expelled and the left most bit will contain 0.
The bitwise operator shifts an expression by a number of digits. So in your example you have
65 which ist binary 0100 0001 shiftet 1 position to the right so you got 0010 0000 which is 32 decimal.
Another example:
48 >> 3 = 6
48 decimal is 0011 0000 binary shifted 3 to the right is 0000 0110 which is 6 decimal.
For your second example I can not help you - I can not image why I would shift an expression by 0 positions but maybe you can find out debugging it?