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
Related
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)
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.
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
This code segment:
(x >>> 3) & ((1 << 5) - 1)
apparently results in a 5-bit integer with bits 3 - 7 of x.
How would you go about understanding this?
Let's look at ((1 << 5) - 1) first.
1 << 5 is equal to 100000 in binary.
When we subtract 1, we're left with 11111, a binary number of five 1s.
Now, it's important to understand that a & 0b11111 is an operation that keeps only the 5 least significant bits of a. Recall that the & of two bits is 1 if and only if both of the bits are 1. Any bits in a above the 5th bit, therefore, will become 0, since bit & 0 == 0. Moreover, all of the bits from bit 1 to bit 5 will retain their original value, since bit & 1 == bit (0 & 1 == 0 and 1 & 1 == 1).
Now, because we shift the bits of x in x >>> 3 down by 3, losing the three least significant bits of x, we are applying the process above to bits 4 to 8 (starting at index 1). Hence, the result of the operation retains only those bits (if we say the first bit is bit 0, then that would indeed be bit 3 to bit 7, as you've stated).
Let's take an example: 1234. In binary, that's 10011010010. So, we start with the shift by 3:
10011010010 >>> 3 = 10011010
Essentially we just trim off the last 3 bits. Now we can perform the & operation:
10011010
& 00011111
--------
00011010
So, our final result is 11010. As you can see, the result is as expected:
bits | 1 0 0 1 1 0 1 0 0 1 0
index | 10 9 8 7 6 5 4 3 2 1 0
^-------^
(x >>> 3)
Shifts x right 3 bits logically, i.e. not sign-extending at the left. The lower-order 3 bits are lost. (This is equivalent to an unsigned division by 8.)
1 << 5
Shifts 1 left 5 bits, i.e. multiplies it by 32, yielding 0b00000000000000000000000000100000.
-1
Subtracts one from that, giving 31, or 0b00000000000000000000000000011111.
&
ANDs these together, yielding only the lower-order 5 bits of the result of x >>> 3, in other words bits 3..7 of the original x.
"How would you go about understanding this?".
I assume that you are actually asking how you should go about understanding it. (As distinct from someone just explaining it to you ...)
The way to understand it is to "hand execute" it.
Get a piece of paper and a pencil.
Based on your understanding of how Java operator precedence works, figure out the order in which the operations will be performed.
Based on your understanding of each operator, write the input patterns of bits on the piece of paper and "hand execute" each operation ... in the correct order.
If you do this a few times with a few values of x, you should get to understand why this expression gives you a 5 bit number.
If you repeat this exercise for a few other examples, you should get to the point where you don't need to go through the tedious process of working it out with a pencil and paper.
I see that #arshajii has essentially done this for you for this example. But I think you will get a deeper understanding if you do / repeat the work for yourself.
One thing to remember about integer and bitwise operations in Java is that the operations are always performed using 32 or 64 bit operations ... even if the operands are 8 or 16 bit. Another thing to remember (though it is not relevant here) is that the right hand operand of a shift operator is chopped to 5 or 6 bits, depending on whether this is a 32 or 64 bit operation.
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.