Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

precedence of ~ and ++ in java

consider this code snippet

int j = 7;
System.out.println(Integer.toBinaryString(j));
j = ~j++;
System.out.println(Integer.toBinaryString(j));

prints

111
11111111111111111111111111111000

what i am expecting to see

111
11111111111111111111111111111001

first i thought it might be the precedence of ~ and ++

if the ~ is evaluated before ++ the answer will be

11111111111111111111111111111001

else if the ++ is evaluated before ~

11111111111111111111111111110111

I searched Oracle tutorials but I couldn't find the answer. Can anyone explain this behavior?

like image 447
Ashraf Saleh Avatar asked May 10 '13 15:05

Ashraf Saleh


2 Answers

Don't forget that the '++' post-increment operator returns the value of j before the increment happened. That is, if 'j' is 7, then 'j++' sets j to 8, but returns 7. ~7 is then the output that you saw, the number ending in three 0 bits.

The '++' post-increment operator can only operate on so-called "L-values". An L-value is a value that actually exists somewhere that code can logically reference -- a variable, or an array element, a parameter or a class field. As soon as you take the value of of an L-value and you apply some numerical operation to it, you get an R-value. R-values are just the value, and they don't refer to any persistent storage where a result could be put. You can assign to L-values but not to R-values -- and so if you tried to '++' an R-value, you would get a compile error.

If the '~' operator went first, then you'd be ++-ing an R-value, as in (~j)++. This would not compile. The fact that the code compiles at all means that the precedence is the other way: ~(j++).

Parentheses like this is the simplest way I know of that you can sort out precedence whenever there is any confusion: Just write three test cases:

  1. The original way that you're uncertain about.
  2. With parentheses forcing one order of operations.
  3. With parentheses forcing the other order of operations.

Run it and see whether #2 or #3 produces the same result as #1. :-)

like image 196
Jonathan Gilbert Avatar answered Oct 28 '22 18:10

Jonathan Gilbert


Both operators are right associative second degree operators, but a simple test reveals that it is the ++ executed first and the BITWISE NOT operation the latter.

int j = 7, z = 7, k = 7;
z = z++;
z = ~z;
k = ~k++;
j = ~j;
j++;
System.out.println(Integer.toBinaryString(z));
// 11111111111111111111111111111000
System.out.println(Integer.toBinaryString(j));
// 11111111111111111111111111111001
System.out.println(Integer.toBinaryString(k));
// 11111111111111111111111111111000
like image 32
flavian Avatar answered Oct 28 '22 16:10

flavian