System.out.println(16 >>> 3)? [duplicate] - java

This question already has answers here:
Difference between >>> and >>
(9 answers)
Closed 9 years ago.
I try the code
System.out.println( 16 >>> 3);
and the output is 2 !
but how does this work? What is the syntax?

16 >> 3 is a bitshift to the right, and is equivalent to dividing by 8 (2 ** 3).
16 -> 00010000
^
\
\
2 -> 00000010

This is called right-shift with zero-fill (also called - unsigned right shift).
To make it easy to understand, for every shift, your number is divided by 2. So:
16 >>> 3 == 16 / 2^3 == 16 / 8 == 2
For more details see, JLS - Shift Operators.
For real visualization, take a look at the bit representation of the two numbers:
16 - 00010000
16 >>> 3 - 00000010 == 2

Another note, the 3 chevrons indicate an unsigned right bit shift. Although it does not make a difference in this example...
The extra > indicates the sign is not reserved, an example:
-128 >> 2 = -128 / 2^2 = -32
The signed bit is retained giving:
(1) 10000000 >> 2 = (1) 100000
11111111 11111111 11111111 10000000 >> 2 = 1111111 11111111 11111111 11100000
If >>> is used then the signed bit is also shifted converting it to a positive number.
-128 >>> 2 = 536870896
11111111 11111111 11111111 10000000 >> 2 = 0011111 11111111 11111111 11100000

The >>> operator is performing an unsigned right-shift of bits, when applied to an integer it has the effect of dividing by two. In particular, if the integer is a power of two, each right-shift exactly halves the value. For example:
16 >>> 1 // returns 8
16 >>> 2 // returns 4
16 >>> 3 // returns 2
In binary form, 16 is represented as 10000. If we shift the value three times to the right it ends up as 00010, which is 2. Also, take a look at the Java tutorial.

16 in binary is 00010000. You are shifting the bits right three positions which results in 00000010 which is 2

This is a bit shift, which is dividing by 2^3 (due to shifting by 3 positions) and truncating(rounding down) as we are not doing fillaround.
When using >>> we move to the right and divide.
When using <<< it goes opposite, so you'd multiply by the correct power of 2.
Bit shifts are a type of bitwise operation that operates on a primitive(almost always number's) bits directly.

It's an unsigned right shift operator, and the above shifts 3 times.
i.e. it divides by 2 each time, giving you 2.
See here for more information on Java operators.

You're using a bitwise shift consult this post
In binary, every 0 is an increasing magnitude of the power 2 for example:
10000 = 16
01000 = 8
00100 = 4
00010 = 2
00001 = 1
The expression 16 >>> 3 in java is saying to move the bit over 3 places, so we are left with 2.

Related

Why am I getting -3 shouldn't I be getting +7

So I'm doing this and I thought it was going to give me +7 but its giving me -3.
public class BitManipulation{
public static void main (String[] args){
System.out.println(~2 | 5 >> ((2 & 2)));
}
}
2 & 2 is 2.
So then you have 5 >> 2 which gives 1 (5 in binary is 101)
So we remain with ~2 | 1
~2 is inverting all the bits. For 8 binary digits (the same goes for 32 but let's keep things concise...) the bits inversion of 00000010 (2) is 11111101. Or-ing this with 1 doesn't change anything.
Now, 11111101 - when treated as a number it is interpreted in two's complement. In this system the most significant bit is the sign, and here it's 1 so the number is negative. To get the absolute value of the number in two's complement we need to invert the bits and add 1.
So inverting 11111101 gives 00000010, and adding 1 gives 00000011, which is 3. Recall the sign was minus, so there you have -3!!! :-)
Try printing off each step like so:
System.out.println(2 & 2);
You will learn that 2 & 2 = 2 (we are performing the bitwise "AND" function on two binary numbers => 0010 AND 0010 = 0010 which is 2), so plug that into the next step:
System.out.println(5 >> 2);
Now you have 5 >> 2 = 1 (we are shifting that binary number to the right padding with zeroes because the number is positive, so 0101 becomes 0001 or 1), and plug that into the final step:
System.out.println(~2 | 1);
And you get ~2 | 1 = -3 (we are performing a bitwise "NOT" followed by a bitwise "OR" operation so 0010 becomes 1101 I believe this is also where it becomes negative and -1101 OR 0001 gives us -1101 or -3)

unsigned right shift by negative number in Java [duplicate]

This question already has answers here:
Negative logical shift
(2 answers)
Closed 7 years ago.
I am having a difficult time wrapping my head around negative unsigned bitwise operators.
For example, I have the code below. It prints out the value 7 and I don't understand why.
int num1 = -37, num2 = -3;
System.out.println( num1 >>> num2);
// Essentially the same as System.out.println( -37 >>> -3);
// I just wanted to emphasize that i am working with Integers
From my knowledge, the number -37 in binary format is as shown below.
11111111 11111111 11111111 11011010 = -37 (in decimal format)
If we are unsigned right shift of 3 ( -37 >>> 3, not -37 >>> -3), from my knowledge (please correct me if my theory is flawed or lacking key concepts), it shifts the bytes to the right by 3 and the 3 bits that fall out on the right most position appear on the left most position in a flipped down state (from zero to one), meaning that we get the following result.
00011111 11111111 11111111 11111011 = 536870907 (in decimal format).
However, if we apply an unsigned right shift of -3 ( -37 >>> -3), we get the result 7. I don't understand why it is returning 7. Could somebody please explain it to me?
It seems counter-intuitive, but when shifting an int, only the last 5 bits of the shift amount are used, according to the JLS, Section 15.19.
If the promoted type of the left-hand operand is int, then only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (ยง15.22.1) with the mask value 0x1f (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.
This means that -3 only has the last 5 bits used, or 29. Here's -3 in bits to show what's going on:
11111111 11111111 11111111 11111101
The last 5 bits are 11101, or 29 in decimal.
The right-shift distance is 29, which means that the first 3 bits are kept and shifted all the way to the right. Taking -37:
11111111 11111111 11111111 11011010
After the unsigned shift of 29 places, 7 is left:
00000000 00000000 00000000 00000111
As you can see, a negative shift amount is confusing at best. Try to avoid it and always attempt to use an actual number between 0 and 31 for the shift amount for shifting ints.

Need help understanding this line

thank you in advance for this basic question.
I am going through a tutorial and I see this line.
int a = (n & 8) / 8
This is supposed to identify whether the fourth bit from the right is a binary representation of 0 or 1. I understand the concept of bits etc, but I do not understand what mathematical equation (if any) this represents.
Would anyone care to explain how this would be written in a mathematical equation? Also, please let me know if i am missing anything else in my understanding of this line. Thank you.
The expression ( n & 8 )
does Logical And of n with 1000 binary.
So that gets the 4th bit from right.
then dividing that by 8, shifts the value right 3 binary places. I.e. it moves the 4th bit to the rightmost place.
That is more clearly expressed as " >> 3"
So your overall expression would be something like:
(n AND 1000 ) >> 3
And that leaves the 4th bit of N in a temporary variable, as bit 0 (rightmost bit).
All the other bits will be zero because of the AND.
8 in decimal is 1000 in binary
so if you do bitwise AND with any number
n & 8
it will stay 8 only if the 4th bit is 1 and
if you divide it by 8 again it will return 1, zero otherwise
For example
for 9 (1001)
9 & 8
would be
1001
& 1000
------
1000
Now for the case where forth bit is 0
for 7 (0111)
7 & 8
would be
0111
& 1000
-----
0000
int a = (n & 8) / 8;
The n & 8 applys a logical AND mask to the 4th bit of n;
n: 11001010 // example value
8: 00001000
result: 00001000
Dividing that number by 8 brings the result to the lowest bit :
result: 00000001
Dividing a number by 2^n shifts the numbers n bits to the right (in the same way that multiplying by 2^n shifts bits to the left).
The result is assigned to variable a, which now contains 0 or 1, depending on the value of the 4th bit.
Bitwise operator works on bits and performs bit-by-bit operation. Assume if a = 60; and b = 13; now in binary format they will be as follows:
a = 0011 1100
b = 0000 1101
a&b=0000 1100
then a&b is also an integer which is further divided by 8 in your example.

Java Operators with Numbers

How it works the & Operator with numbers?
For example:
x = 8 & 4;
and the answer is 0.
How can i find the answer without using java or any other program?
You can find the answer without using Java converting the numbers into binary format:
4 = 0100
8 = 1000
If you perform an AND operation on each bit, you get:
0 & 1 = 0
1 & 0 = 0
0 & 0 = 0
0 & 0 = 0
That's why it's zero.
Java has three kinds of "AND" operators - the logical one, which is &&, a bitwise one, which is &, and a & on booleans, which does not short-circuit. Java compiler can distinguish between the kinds of operators by examining the type of the operands.
Bitwise operator takes binary representations of its operand, performs "AND" on each bit, and returns the result as a number.
For 4 and 8, bitwise "and" is zero, because they do not have 1 bits in common:
00000100 -- 8
00001000 -- 4
--------
& 00000000 -- 0
For other numbers, say, 22 and 5, the result would be different:
00010110 -- 22
00000101 -- 5
--------
& 00000100 -- 4
& is a bitwise and operator ... the binary values of 8 and 4 are
8 = 1000
4 = 0100
if you know how AND operator works then you know that
1 & 0 = 0;
so after a bitwise AND, there will be all 0

How do bitwise operator results occur?

I'm quite surprised that I can't find an answer to this simple sounding question on Google. After checking about a dozen different pages I'm just going to ask here ...
According to this page, 3 & 5 result in 1. Also, 3 | 5 result in 7. The only question I have is simply:
How do we get 1 for 3 & 5?
How to we get 7 for 3 | 5?
Also, what about negative numbers?
How does 8 & -8 result in 8?
Sure enough, writing the following in java:
System.out.println(3&5);
System.out.println(3|5);
System.out.println(8&-8);
Produces this output:
1
7
8
But again, how are these results determined / calculated?
3 & 5:
0011
0101
----- AND
0001 == 1
3 | 5:
0011
0101
----- OR
0111 == 7
Negation in Java is defined to be two's complement negation (which is extremely common).
So -x = ~x + 1 = ~(x - 1).
8 & -8:
00001000 //8
11111000 //-8
-------- AND
00001000 // 8
Using the last definition of negation, the -1 first borrows through all rightmost zeroes (if there are any), setting them as it goes, until it hits a 1, which it resets, anything to the left of that is left unmodified. The complement then restores the rightmost zeroes and the rightmost one (all of which were effectively complemented by that -1), and complements everything to the left of the rightmost one:
00001000 // 8
00000111 // 8 - 1 = 7
11111000 // -8
Note that -8 is only 11111000 if you're working with 8 bit numbers. If had you more bits, there would be more 1's to the left. If you have only 4 bits, you run into some kind of trouble because -8 turns out to have the same representation as 8, and so -8 is (in 4 bit math) a number that is its own negative (like zero).
Actually, 8 is not a very good example, because it's too simple. Let's do 100 & -100 (hundred, not 4):
01100100 // 100
01100011 // 99
10011100 // -100
Now & with 100:
01100100 // 100
10011100 // -100
-------- AND
00000100 // 4
In general, x & -x isolates the rightmost 1. Neither the rightmost zeroes not the rightmost 1 are affected by negation, and so for only that part of the number, it looks like you're doing x & x (which is of course x). The upper part, to the left of the rightmost one, is complemented, so everywhere you had a 1 becomes 0, and everywhere you had a 1 becomes 0. 0 & 1 = 0, so that gives 0 everywhere.
3 & 5 => 1
3 in binary is 0011.
5 in binary is 0101.
apply the bitwise and
0011
& 0101
------
0001 => 1 in decimal
Take the same idea, along with the truth tables for each op, and apply them to your specific problems.
You need to turn the number into binary at that point you need to remember that "b1 and b2=1" only if they are both 1, and "b1 or b2=0" only if they are both 0.
So for example
5 or 3 = 101 or 011 = 111 = 7
5 and 3 = 101 and 011 = 001 = 1

Categories