This question already has answers here:
Difference between >>> and >>
(9 answers)
Closed 5 years ago.
int z = -1; int m = z>>1; System.out.println("the values is " +m);
Output is
the values is -1
but my doubt is how it happening internally, Can any explain? Step by step procedure.
int z = 2; int m = z>>1;
the z value in binary
00000000 00000000 00000000 00000010 ,
After the value is shifted then the m value in binary will be as
00000000 00000000 00000000 00000001 , when I print m value it will be as 1, but my question is, what is happening if I use negative value for z variable and when I assign z value with -1 why output variable has -1 itself? ( Two complement will happen are not?)
As described in JLS Sec 15.19:
The value of n >> s is n right-shifted s bit positions with sign-extension. The resulting value is floor(n / 2^s).
So, you are calculating -1 >> 1 == floor(-1 / 2) == floor(-0.5) = -1.
Related
Java Integer class has the static method highestOneBit method which will return a value with a single one-bit, in the position of the highest-order one-bit in the specified value, or zero if the specified value is itself equal to zero.
For example input of int 17 will return 16; As 17 can be represented in binary as 10001 so it will return the furthest bit left which is equal to 16.
And in Integer class it has the following implementation in Java doc.
public static int highestOneBit(int i) {
// HD, Figure 3-1
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i - (i >>> 1);
}
I just want to know the logic behind implementing it this way and the logic behind using shift operations
. Can any one put some light on it.
This algorithm calculates for a given i whose binary representation is:
0..01XXXXXXX...XXXX
the value
0..011111111...1111
That's what the 5 |= operators do.
Then, in the return statement, it subtracts from it that value shifted right by one bit
0..001111111...1111
to get the result
0..010000000...0000
How does it work:
The highest possible 1 bit the the 32nd (left most) bit. Suppose the input number has 1 in that bit:
1XXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
You or that value with the value shifted right by 1 (i >> 1) and get
11XXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
Then you or that new value with the value shifted right by 2 (i >> 2) and get
1111XXXX XXXXXXXX XXXXXXXX XXXXXXXX
Then you or that new value with the value shifted right by 4 (i >> 4) and get
11111111 XXXXXXXX XXXXXXXX XXXXXXXX
Then you or that new value with the value shifted right by 8 (i >> 8) and get
11111111 11111111 XXXXXXXX XXXXXXXX
Finally you or that new value with the value shifted right by 16 (i >> 16) and get
11111111 11111111 11111111 11111111
If the highest 1 bit is smaller than the 32nd bit, these operations still turn all the bits to the right of it to 1 and keep the remaining (higher bits) 0.
The i |= statements help to compute a sequence of ones that is the same length as i. For example, for 101011 it computes 111111. I've explained how it works in this answer (I can't retype it right now since I am on mobile).
So basically, once you have the string of ones, subtracting itself shifted right one bit gives the H.O. bit.
111111 - (111111 >>> 1) = 111111 - 011111 = 100000
The first five lines (i |= (i >> x)) will set every bit below the highest 1-bit to 1. Then, the final line will subtract every 1-bit below the highest one, so that only the highest 1-bit will remain.
For simplicity, let's pretend an int was 8 bits. The code would in that case be like this:
public static int highestOneBit(int i) {
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
return i - (i >>> 1);
}
Now, let's say we have the value 128 (10000000). This is what would happen:
// i == 10000000
i |= (i >> 1); // i = 10000000 | 11000000 = 11000000
i |= (i >> 2); // i = 11000000 | 11110000 = 11110000
i |= (i >> 4); // i = 11110000 | 11111111 = 11111111
return i - (i >>> 1); // 11111111 - 01111111 = 10000000
The >> is an arithmetic right shift, so it will preserve the signed bit.
The last >>> is a logical right shift, which will not preserve the signed bit. It will always insert zeroes on the left side.
Now, let's try with 64 (01000000):
// i == 01000000
i |= (i >> 1); // i = 01000000 | 00100000 = 01100000
i |= (i >> 2); // i = 01100000 | 00011000 = 01111000
i |= (i >> 4); // i = 01111000 | 00000111 = 01111111
return i - (i >>> 1); // 01111111 - 00111111 = 01000000
public class UpCase {
public static void main(String[] args) {
int t;
byte val;
val = 123;
for (t = 128; t > 0; t = t / 2) {
System.out.println(t);
if ((val & t) != 0) System.out.println(" 1");
else System.out.println(" 0");
}
}
}
In particular, I am not sure why we are using val=123? I understand that this program will print out 123 in binary but why is that the case? How does this work? I do understand however, the principles of the & operator and how you can turn on and off bits but I am not sure how it works in this particular example?
This program will print out the binary digits of the number in val from MSB to LSB by comparing it to each power of 2:
123 : 01111011 &
128 : 10000000 =
00000000
00000000 != 0 => false, print 0
123 : 01111011 &
64 : 01000000 =
01000000
01000000 != 0 => true, print 1
123 : 01111011 &
32 : 00100000 =
00100000
00100000 != 0 => true, print 1
// repeat for 2^4-2^1...
123 : 01111011 &
1 : 00000001 =
00000001
00000001 != 0 => true, print 1
Very simple:
It just checks if the value (123 in this case) using the bitwise operator &. The result of that is 1 or 0, this process is repeated for the following value 0.5t etc until t=0, resulting in the binary string for this value 123.
I'm trying to learn bit shifting/masking. Here is my code:
int health = 511; // max 512, 9 bits
int aimAngle = 510; // max 512, 9 bits
int test = 511; // max 512, 9 bits
boolean bool = false; // max 1, 1 bit
int packed;
packed = health | aimAngle << 9 | test << 18 | (bool?1:0) << 19;
Debug.log("health: " + ((packed ) & 0b111111111));
Debug.log("aimAngle: " + ((packed >> 9) & 0b111111111));
Debug.log("test: " + ((packed >> 18) & 0b111111111));
Debug.log("bool: " + ((packed >> 19) & 0b1));
I'm getting all the values correctly except bool. It's always 1. What is wrong? Can't I shift zero to the beginning?
test is up to nine bits long. You shift it right 18 places. Therefore it occupies bits 18 to 27. You need to shift bool to place 28 to avoid it, not to place 19.
The 19th digit of packed is the second digit of test, which is a 1.
Learning JAVA, i was trying to test the upper limit of while loop which goes on incrementing an int.Please see the program below :
public class Test {
public static int a(){
int a = 10;
while(a > 9 )
++a;
return a;
}
public static void main(String[] argc) {
Test t = new Test();
int k = t.a();
System.out.println("k = "+(1 * k));
}
}
I am aware that 32 bits range is from -2,147,483,648 to 2,147,483,647, so on the basis of that, i was expecting output as 2,147,483,647 but instead i am getting :
k = -2147483648
I even tried
System.out.println("k = "+(1 * k/2));
but still output is :
k = -1073741824
Question :
Why is solution negative when it should be positive?
You are incrementing your a int by 1 until it reaches 1 + Integer.MAX_VALUE, which shifts its value to -2147483648 == Integer.MIN_VALUE.
Here's your loop commented:
// "infinite" loop as a is assigned value 10
while(a > 9)
// when a reaches Integer.MAX_VALUE, it is still incremented by 1
++a;
// loop condition now false, as value for a has shifted to -2147483648
return a;
What is happening is called integer overflow.
Maximum 32-bit integer value in binary is:
0111 1111 1111 1111 1111 1111 1111 1111
When you add 1 to this number you get:
1000 0000 0000 0000 0000 0000 0000 0000
This is the twos compliment, or -2,147,483,648. Since any negative number is less than 9, the while loop exits.
You increment the value until it reaches the positive limit and it becomes all bits but the sign bit becomes 1.
0x7FFFFFFF = 01111111 11111111 11111111 11111111
This is binary representation of 2147483647, which is INT_MAX. When you increment it by one once again, it becomes
0x80000000 = 10000000 00000000 00000000 00000000
which is equal to INT_MIN, -2147483648.
Now,
2147483647 is greater than 9 so your loop continues. One more increment and oops, suddenly it is -2147483648 which is smaller than 9. This is the point where your loop condition fails.
If we look at Oracle docs on int values We can find out that:
The operators that work on the int primitive value do not indicate overflow or underflow
The results are specified by the language and independent of the JVM version as folows:
Integer.MAX_VALUE + 1 is the same as Integer.MIN_VALUE
Integer.MIN_VALUE - 1 is the same as Integer.MAX_VALUE
I've seen in a few places the following code recommended to add to numbers and divide by 2, particularly in the context of finding a middle index in an array to be quicksorted.
int middle = ( low + high ) >>> 1;
opposed to
int middle = ( low + high ) / 2;
Correct me if I'm wrong on the basics. Right shifting bits 1 position (>> 1) has the effect of dividing by 2. Since in java int is signed we don't want to change the first bit, so we use the unsigned shift operator >>>. I've heard the claim this prevents integer overflow but I don't see how. According to the docs arithmetic operators have presidence over shifts. Which is a moot point since brackets are being used anyways. If whatever's in the the ( ) overflows why would something outside matter?
When you add two ints, the number may overflow into a negative number, but the bits are still there, and no information is lost; it could be interpreted as an unsigned int, if Java had such a type. Let's try to average 2^30 and 2^30 + 2 with this method.
01000000 00000000 00000000 00000000
+ 01000000 00000000 00000000 00000010
-----------------------------------
10000000 00000000 00000000 00000010 // overflow
In Java, this would be interpreted as -2^30 + 2, but if it were unsigned, then it would be interpreted as 2^31 + 2.
Java's unsigned bit-shift-right operator, >>>, shifts in a zero instead of sign-extending.
10000000 00000000 00000000 00000010 >>> 2 yields
01000000 00000000 00000000 00000001
And that's the correct answer, 2^30 + 1.
That is contrast to the signed bit shift operator, >>, which sign-extends:
10000000 00000000 00000000 00000010 >> 2 yields
11000000 00000000 00000000 00000001
That's incorrect, -2^30 + 1.
This will work for averaging two positive int values. But because the result will always be non-negative, this won't work if the correct average value is negative.
Real example:
int low = 0x40000000;
int high = 0x40000002;
int unsigned = (low + high) >>> 1;
int signed = (low + high) >> 1;
System.out.println("low =" + low);
System.out.println("high =" + high);
System.out.println("unsigned=" + unsigned);
System.out.println("signed =" + signed);
The output:
low =1073741824
high =1073741826
unsigned=1073741825
signed =-1073741823
I noticed that there is a typo:
>> 2
should be:
>> 1
and
>>> 2
should be
>>> 1
for the shift operator examples...