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.
Related
int number = 3;
System.out.println(number & 1 << 2);
Given this snippet where I am performing bitwise AND to number and then left shifting by 2, Why is the result 0 and not 4 (0100)?
Make it (number & 1) << 2 because what you are doing means shift 1 << 2 times and then & that with number.
First, as multiple people have already mentioned, the & operator's precedence is smaller than <<'s. So your code would look like this: number & (1 << 2). Let's imagine your code looked like this instead: (number % 1) << 2. Now, what does this do?
First, let's talk about the & operator. What does it do? In short, it will apply an AND gate to each bit of the two given numbers, recording the result of the gate in a new number:
a 0 0 1 1
b 1 1 1 0
result 0 0 1 0
An AND gate works in the following way: the result of this gate is 1 only when both inputs are 1, otherwise, the output of the gate is 0.
In your case, you have the following:
a ...number
b 0 0 0 0 0 0 0 1
Since each bit but the first one of b is 0, the result will be all 0s, except for the first bit, which will be whatever the first bit of number was (note that a & 1 is virtually equivalent to a % 2).
The shift operator now will shift the only remaining bit to the left 2 bits, which will virtually multiply it by 4.
So, for example, if number was 3, 3 & 1 would be 1 (the first bit of 3 is 1), and then 1 would be shifted over 2 bits, so the result would be 4.
In fact, the expression (number & 1) << 2 will produce only two values:
4, when the number is odd (its first bit is 1)
0, when the number is even (its first bit is 0)
This question already has answers here:
n & (n-1) what does this expression do? [duplicate]
(4 answers)
Closed 6 years ago.
I saw this efficiently written code at Leetcode.com
public static boolean isPowerOfTwo(int n) {
return n>0 && ((n&(n-1))==0);
}
This works awesomely fine but I am not able to figure out the working of single '&' in the code.
Can some onetake efforts to explain how the code works?
And by the same logic what would eb the code to determine if an integer is power of 3?
The single & is a bitwise 'and' operator (as opposed to &&, which acts on booleans).
So when you use & on two integers, the result is the logical 'and' of their binary representations.
This code works because any power of 2 will be a 1 followed by some number of 0s in binary (eg, 4 is 100, 8 is 1000, etc). Any power of 2, less one, will just be all 1s (eg. 3 is 11, 7 is 111).
So, if you take a power of 2, and bitwise and it with itself minus 1, you should just have 0. However, anything other than a power of 2 would give a non-zero answer.
Example:
1000 = 8
0111 = 7 (8-1), and '&'ing these gives
0000 = 0
However, if you had something like 6 (which isnt a power of 2):
110 = 6
101 = 5 (6-1), and '&'ing these gives
100 = 4 (which isnt equal to 0, so the code would return false).
I hope that makes it clear!
The & in Java is a bitwise and operator. It takes two integers and performs an and operation on each bit, producing an int where each bit is set to '1' if and only if that bit was '1' in both operands. The code uses the understanding that any power of two in binary is a '1' followed by some number of '0's. This means that subtracting one will change ALL the bits of the number. For any non power of two, there will be at least one nonzero digit after the first, so the first digit will remain the same. Since performing an AND on two different values always produces '0', ANDing the original number and itself minus one will produce 0 if and only if that number is a power of two. Because this is a trick with binary number specifically, it wouldn't work for finding powers of other bases.
To understand how this function works you need to understand how binary numbers are represented. If you don't I suggest reading a tutorial such as Learn Binary (the easy way).
So say we have a number, 8, and we want to find out if it's a power of two. Let's convert it to binary first: 1000. Now let's look at 8-1 = 7's binary form: 0111. The & operator is for binary AND. When we apply the AND operator to 8 and 7 we get:
1000
0111
&----
=0000
Every integer which is a power of 2 is a 1 followed by a non-negative amount of zeroes. When you subtract 1 from that number you will always get a 0 followed by a sequence of 1s. Since applying the AND operation to those two numbers will always give you 0, you can always verify if it's a power of 2. If the number is not a power of 2, when you subtract 1 from it it won't invert all of its digits and the AND test will produce a positive number (fail).
Its an bitwise operator :
if we take 2 exponent 3 equals to 8,
e.g 2³ = 2×2×2 = 8
now to calculate if 8 is a power of 2, it works like this:
n&(n-1) --> 8 AND (8-1) --> 1000 AND 0111 = 0000
thus it satisfies the condition --> (n&(n-1))==0
The single "&" performs a bitwise AND operation, meaning that in the result of A & B with A and B being integers only those bits will be set to 1 where both A and B have a 1.
For example, lets look a the number 16:
16 & (16 - 1) =
00010000 &
00001111 =
00000000
This works for powers of two because any power of two minus one will have all lower bits set, or in other words n bits can express n different values including zero, therefore (2^n)-1 is the highest value that can be expressed in n bits when they're all set.
I hope this helps.
Powers of three are a bit more problematic as our computers don't use ternary numbers. Basically a power of three is any ternary number that only has one digit different from zero and where that digit is a "1" just like in any other number system.
From the top of my head, I can't come up with anything more elegant than repeatedly doing modulo 3 until you reach one as a division result (in which case you'd have a power of three) or a nonzero modulo result (which would mean it's not a power of three).
Maybe this can help as well: http://www.tutorialspoint.com/computer_logical_organization/number_system_conversion.htm
I am trying to understand the command "someByte << 2" in java. For what is it for? At the iscsi docmentation there is a caching mode page saying about DEMAND READ RETENTION PRIORITY and WRITE RETENTION PRIORIRY.
at the source there is this code for these messages:
// serialize byte 3
b = (byte)((demandReadRetentionPriority << 4) | writeRetentionPriority);
buffer.put(b);
Why do they use "<< 4" command with demandReadRetentionPriority and not with writeRetentionPriority? And what does << means in that case?
Thanks.
You can see from the documentation that the demandReadRetentionPriority is in the upper 4 bits (bits 7,6,5, and 4) of the byte and writeRetentionPriority is stored in the lower 4 bits (3,2,1, and 0) of the byte.
The code you provided is simply shifting the value stored in the demandReadRetentionPriority variable to the upper 4 bits. The << is a bit shift operation.
For example, if the value of demandReadRetentionPriority were 1 then it would be shifted 4 bits and the byte would have a binary representation as follows:
00010000
And in order for one of the lower bits of b to be set to 1, the corresponding bit in writeRetentionPolicy would have to also be set to 1, since the lower 4 bits of demandReadRetentionPolicy will be 0 after the bit shift.
<< is the "Signed left shift" operator, a bit shifting operator.
Example:
You have stored the number 279 that would be 100010111 in decimal. When you shift 4 steps to the left you get 1000101110000 (2224) because it will "move" the decimal number to the left and fill the spaces with zeroes.
100010111 << 4
=> 1000101110000
++++
Shifting operations are very fast because they are usually implemented in the hardware as a single machine instruction.
| is also an operator on the bit-level: The bitwise inclusive OR.
Summary of operators in java
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.
I have a simple question - I need to write a function for my program to change the 3rd bit of a given byte.
I wrote those lines :
public byte turnOn(Byte value)
{
int flag = 8;
value = (byte) (value | flag);
return value;
}
I'm not sure if it's the right way to do that, because I saw also this way (with which I am unfamiliar)
value = (byte) (value | (1 << 2) );
which way is better, and what does 1 << 2 means (2 means the third bit, but what is the 1 )
Thanks!
1 << 2 means 1 shifted two bits to the left. Since shifting left by one bit is similar to multiplying by two, this gives 4. In binary, this is
00000100
i.e. the 3rd bit from the right is set.
The constant 1 is used since that number only has a single bit set - the rightmost bit. After shifting left, only the 3rd bit (from the right) is set:
00000001 original value
00000010 after shifting left once
00000100 after shifting left again
I prefer using 1 << 2 instead of a constant like 8, as it makes it clearer which bit is being set. It also prevents you inadvertently using a constant that has multiple bits set - unless you actually want that, of course. Even then, it's clearer in my opinion to add together several bits, for clarity:
final int bitsToSet = (1 << 2) + (1 << 5);
4 (or 1 << 2) is 00000100 in binary¹. ORing with this mask sets the third least significant bit (or the fifth significant bit in a byte).
8 (or 1 << 3) is 00001000 in binary, so you're setting the fourth least significant bit (or the fifth one of a byte).
It does not matter which expression you use, the shifting just makes it clear you're using a bitmask. Alternatively, you can use the hexadecimal 0x04 which is (imho) easier to translate to the binary bitmask.
1 The leading zeros do not change the value, but should simplify counting the position of the set bit in a byte.
(1 << 2) will left-shift the value 1 twice. Generically, (x << y) means x * (2 ^ y). So 1 << 2 is 4.
Generally speaking, it should not matter whether you use the bit-shift or bit-set method. The compiler should optimize either way.
That said, are you looking for the 3rd bit, indexed from 0 or indexed from 1? If you're looking for the third-right-most bit starting at index 1, you want your flag to be 4 instead of 8. Additionally, the | operator is the set-value operator. If you literally want to "change" the bit, you want to use the ^ operator -- bitwise XOR -- which is the toggle-value operator.
Does that make sense?