Unary operator precedence in java - java

Now, according to this website, Unary post-increment has more precedence than Unary pre-increment. I presume it meant, that x++ is done before ++x.
However, when tried with the following expression, I've faced problems
int var1=10;
int b= --var1 + ++var1 + var1++;
Now, if var1++ executes first, then according to me,
b = --var1 + ++var1 + 10
Now, if I think it should do ++var1 before --var1, as it mentions that the Associativity is Right to Left. I suppose, it means do things on right, before the ones on the left
This, However, doesn't give the correct answer. The Correct Answer is 29, while I get 33. Why is it so ?

I presume it meant, that x++ is done before ++x.
No, it doesn't mean that. I've previously blogged about how I find viewing precedence in terms of execution order is problematic. It may well be valid in a computer-science-strict way, but it ends up confusing people.
I find it much easier to think about it as grouping. Likewise I think it's easiest to think of associativity as like precedence, but for operators of equal precedence. Evaluation order is always left-to-right.
So this:
int b = --var1 + ++var1 + var1++;
is grouped as if it were written:
int b = (--var1) + (++var1) + (var1++);
That's then equivalent to:
int b = ((--var1) + (++var1)) + (var1++);
(Due to binary + having left-to-right associativity.)
That's then effectively:
int tmp1 = --var1; // tmp1 = 9, var1 = 9
int tmp2 = ++var1; // tmp2 = 10, var1 = 10
int tmp3 = tmp1 + tmp2; // tmp3 = 19
int tmp4 = var1++; // tmp4 = 10, var1 = 11
int tmp5 = tmp3 + tmp4; // tmp5 = 29
int b = tmp5; // b = 29
... which confirms what you've observed.
Of course, you should always try to avoid having code as convoluted as this in the first place...
To demonstrate the evaluation order part, consider this expression:
int result = a() + b() * c();
Precedence means that's grouped as:
int result = a() + (b() * c());
That's equivalent to:
// Evaluate LHS of +, which is just a()
int tmp1 = a();
// Evaluate RHS of +, which is b() * c()
// First evaluate LHS of *, which is b()
int tmp2 = b();
// Next evaluate RHS of *, which is c()
int tmp3 = c();
// Now we can evaluate *:
int tmp4 = tmp2 * tmp3;
// Now we can evaluate +:
result = tmp1 + tmp4;
As we're executing methods, we can observe that execution order really easily:
public class Test {
public static void main(String[] args) throws Exception {
int result = a() + b() * c();
}
public static int a() {
System.out.println("a()");
return 3;
}
public static int b() {
System.out.println("b()");
return 4;
}
public static int c() {
System.out.println("c()");
return 5;
}
}
That prints:
a()
b()
c()
... which confirms the execution order shown in my expansion.

The sum --var1 + ++var1 + var1++ translates to:
9 + 10 + 10
since the various vars are changed as the sum is processed; obviously var1++ increments after the value is used, and ++var increments before it is used. The final value of var1 would be 11.

Related

compound assignment operator in java [duplicate]

This question already has an answer here:
Order of operations for compound assignment operators in Java
(1 answer)
Closed 6 years ago.
int a = 2;
int b = 3;
int c = 10;
a +=(a += b) + c; // this will be same as --> a = a+((a= a+b) +c);
/* 2+((2=2+3)+10)
after adding 2+3
now value a = 5;
5 +((5)+10)
5 + (15)
a = 20
*/
System.out.println("a: "+a); // a:17
when i execute above program the answer is a:17 why not a:20 ?
according to me.
After resolving (a += b) now the value of a should be 5 then (a += b) + c would be 15 and after that a +=(a += b) + c; should be 20
please help me understand thanks.
The compound assignment operator stores the original value of the left operand before evaluating the second operand and performing the compound assignment (addition + assignment in this example).
Therefore
a += (a += b) + c;
is equivalent to :
int temp = a;
a = temp + (a += b) + c;
2 + 2 + 3 + 10 = 17
This is a good example of where order of evaluation and precedence don't match. They usually do which makes it confusing when there is a difference, as you mention the expression is evaluated left to right like this
int s = a; // stack
int t = a + b; // second stack value.
s += t;
s += c;
a = t;
a = s;
Note the (a+=b) is the same as (a+b) in this case.
In Java, you can replace a += b with a = a + b. And that is very important.
Hence your expression is equivalent to
a = a + (a = a + b) + c
Note that this will be evaluated as a = Term1 + Term2 + Term3 and in the order left to right.
Term1 is 2.
Term2 is the only tricky one. It is 5 (and has the side-effect of increasing a to 5 but that gets clobbered by the eventual assignment).
Term3 is 10.
That recovers the total, 17.
Note that the behaviour of this expression in C and C++ is undefined.
It is a bit tricky to understand. Although you have a += b on the right-hand side, that doesn't change the value of a that's used for the += at the beginning of the expression; that will still be 2. E.g.:
a += (a += b) + c;
a = 2 + (a[still 2] += 3) + 10
a = 2 + (5) + 10
a = 17
The a += b on the right-hand side is really just a a + b, since this is all on the right-hand side of a += already directed at a.
Details in JLS§15.26.2: Compound Assignment Operators.
First you do a+=b so 2+3 you have 5. Then a+= your answer (here 5) so 2+=5 = 7. Then 7+10 = 17

Integer + 1 and memory

public class test{
public static void main(String[] args) {
Integer i = new Integer(400);
Integer x = i;
i = i + 1;
x == i;
}
}
Can anybody help me to understand the memory's changed about heap and stack. If x == i compares memory's address ?
The only line which is not self-explanatory here is:
i = i + 1;
Because of autoboxing, this line is actually equivalent to:
i = Integer.valueOf(i.intValue() + 1);
^ auto-unboxing
^ autoboxing
So the intValue of i is moved to the stack; 1 is added; then a new instance of Integer may be created on the heap (since values as high as 401 are not guaranteed to be cached by Integer internally).
As for x == i: assuming you mean something like
System.out.println(x == i);
That would always print false, since x and i are different instances.
example: i point to address a1;
x = i means x point to address a1;
i = i + 1 means x point to address a2;
so x == i will return false as a1 doesn't equals a2.

Difference between a+=b and a=a+b in Java [duplicate]

This question already has answers here:
Difference between a += 10 and a = a + 10 in java? [duplicate]
(5 answers)
Closed 8 years ago.
I've been told that there are differences between a+=b; and a=a+b; which can result in only one of those being legal depending on the type declerations.
Does anyone have an example of this?
There is basically no difference, however there is a subtle difference.
The arithmetic assignment operators do an implicit cast. e.g.
byte a = 1;
int b = 2;
a += b; // compiles
a = a + b; // doesn't compile as a byte + int = int
a = (byte) (a + b); // compiles as this is the same as +=
For more weird examples.
int a = 5;
a += 1.5f;
// a == 6
char ch = '0'; // (char) 49
ch *= 1.1; // ch = '4';
long l = Integer.MAX_VALUE;
l += 0.0f; // i = (long ) ((long ) l + 0.0f)
// i == Integer.MAX_VALUE + 1L; WTF!?
// l is no longer Integer.MAX_VALUE due to rounding error.
The JLS (section 15.26.2) says:
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
The presence of the type-cast means that there are a couple of edge cases where a = a op b means something different to a op= b.
See Peter Lawrey's answer for one example. It is when a is a byte and b is an int and the "op" is +. The "gotcha" is a + b produces an int, which then can't be assigned to a ... without a typecast.
The same scenario applies with other types for a and b and for other arithmentic and bitwise operators.
int a = 10;
int b = 20;
a=a+b; // 30
a+=b; // 30
System.out.println(a);
Both will give the same answer.

Why doesn't the post increment operator work on a method that returns an int?

public void increment(){
int zero = 0;
int oneA = zero++; // Compiles
int oneB = 0++; // Doesn't compile
int oneC = getInt()++; // Doesn't compile
}
private int getInt(){
return 0;
}
They are all int's, why won't B & C compile? Is it to do with the way ++ operator differs from = 0 + 1;?
Invalid argument to operation ++/--
i++ is an assignment to a variable i.
In your case, zero++ is an equivalent to zero = zero + 1. So 0++ would mean 0 = 0 + 1, which makes no sense, as well as getInt() = getInt() + 1.
More accurately :
int oneA = zero++;
means
int oneA = zero;
zero = zero + 1; // OK, oneA == 0, zero == 1
int oneB = 0++;
means
int oneB = 0;
0 = 0 + 1; // wrong, can't assign value to a value.
int oneC = getInt()++;
means
int oneC = getInt();
getInt() = getInt() + 1; // wrong, can't assign value to a method return value.
From a more general point of view, a variable is a L-value, meaning that it refers to a memory location, and can therefore be assigned. L in L-value stands for left side of the assignment operator (i.e. =), even if L-values can be found either on the left side or the right side of the assignment operator (x = y for instance).
The opposite is R-value (R stands for right side of the assignment operator). R-values can be used only on the right side of assignment statements, to assign something to a L-value. Typically, R-values are literals (numbers, characters strings...) and methods.
Because as stated in JLS:
The result of the postfix expression must be a variable of a type that
is convertible (§5.1.8) to a numeric type, or a compile-time error
occurs.
getInt() is not int
getInt() returns int
++ operator does two things increment + assignment
So for ++ operator to work you need a variable to store the result of increment operation which 0 and getInt() both are not.
The pre- and post- operators only operate on variables or lvalues as they are called. lvalue is short for left value, i.e. something that can stand to the left in an assignment.
In your example:
zero = 1; // OK
0 = 1; // Meaningless
getInt() = 1; // Also meaningless
//jk
Both B and C make the compiler say:
unexpected type, required: variable, found: value
So you can't increment a value, only a variable.
Why doesn't the post increment operator work on a method that returns an int?
Because it is a getter method, and it doesn't make sense to change a value via getter.
int z = x + y++;
is equivalent to:
int z = x + y;
y = y + 1;
so it is not valid to have something like:
int z = x + getY()++;
which is equivalent to:
int z = x + getY();
getY() = getY() + 1; // invalid!
0++
It is equivalent to 0 = 0 + 1; and certainly it is not possible.
i.e. it has to be l-value to assign to it.
getInt()++;
Similar reason here.
Because 0 is a rValue (i.e. You can use it only from right of the assignment operator) not a lValue.
++ operator increments the value and sets it to itself therefore 0++ will give You an error.
My answer its kind of "out of the box".
When I have doubt about an operator usage, I think "which its the overloaded function equivalent" of this operator ?
I, know, that Java operators doesn't have operator overloading, its just an alternative way to make a solution.
In this case:
...
x++;
...
should be read as:
...
int /* function */ postincrement (/* ref */ int avalue)
{
int Result = avalue;
// reference value,
avalue = avalue + 1;
return Result;
}
...
postincrement(/* ref */ x);
...
And:
...
++x;
...
...
int /* function */ preincrement (/* ref */ int avalue)
{
// reference value,
avalue = avalue + 1;
int Result = avalue;
return Result;
}
...
preincrement(/* ref */ x);
...
So, both, versions of "++", work as a function that receives a variable parameter by reference.
So, a literal value like "0++" or a function result like "getInt()++", are not a variable references.
Cheers.
postincrement and preincrement can apply only with the help of variable.So the first case compile.
Since function return is RHS expression and pre/post increment/decrement operations can be applied to LHS expressions only.

Is there a difference between x++ and ++x in java?

Is there a difference between ++x and x++ in java?
++x is called preincrement while x++ is called postincrement.
int x = 5, y = 5;
System.out.println(++x); // outputs 6
System.out.println(x); // outputs 6
System.out.println(y++); // outputs 5
System.out.println(y); // outputs 6
yes
++x increments the value of x and then returns x
x++ returns the value of x and then increments
example:
x=0;
a=++x;
b=x++;
after the code is run both a and b will be 1 but x will be 2.
These are known as postfix and prefix operators. Both will add 1 to the variable but there is a difference in the result of the statement.
int x = 0;
int y = 0;
y = ++x; // result: x=1, y=1
int x = 0;
int y = 0;
y = x++; // result: x=1, y=0
Yes,
int x=5;
System.out.println(++x);
will print 6 and
int x=5;
System.out.println(x++);
will print 5.
In Java there is a difference between x++ and ++x
++x is a prefix form:
It increments the variables expression then uses the new value in the expression.
For example if used in code:
int x = 3;
int y = ++x;
//Using ++x in the above is a two step operation.
//The first operation is to increment x, so x = 1 + 3 = 4
//The second operation is y = x so y = 4
System.out.println(y); //It will print out '4'
System.out.println(x); //It will print out '4'
x++ is a postfix form:
The variables value is first used in the expression and then it is incremented after the operation.
For example if used in code:
int x = 3;
int y = x++;
//Using x++ in the above is a two step operation.
//The first operation is y = x so y = 3
//The second operation is to increment x, so x = 1 + 3 = 4
System.out.println(y); //It will print out '3'
System.out.println(x); //It will print out '4'
Hope this is clear. Running and playing with the above code should help your understanding.
I landed here from one of its recent dup's, and though this question is more than answered, I couldn't help decompiling the code and adding "yet another answer" :-)
To be accurate (and probably, a bit pedantic),
int y = 2;
y = y++;
is compiled into:
int y = 2;
int tmp = y;
y = y+1;
y = tmp;
If you javac this Y.java class:
public class Y {
public static void main(String []args) {
int y = 2;
y = y++;
}
}
and javap -c Y, you get the following jvm code (I have allowed me to comment the main method with the help of the Java Virtual Machine Specification):
public class Y extends java.lang.Object{
public Y();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_2 // Push int constant `2` onto the operand stack.
1: istore_1 // Pop the value on top of the operand stack (`2`) and set the
// value of the local variable at index `1` (`y`) to this value.
2: iload_1 // Push the value (`2`) of the local variable at index `1` (`y`)
// onto the operand stack
3: iinc 1, 1 // Sign-extend the constant value `1` to an int, and increment
// by this amount the local variable at index `1` (`y`)
6: istore_1 // Pop the value on top of the operand stack (`2`) and set the
// value of the local variable at index `1` (`y`) to this value.
7: return
}
Thus, we finally have:
0,1: y=2
2: tmp=y
3: y=y+1
6: y=tmp
When considering what the computer actually does...
++x: load x from memory, increment, use, store back to memory.
x++: load x from memory, use, increment, store back to memory.
Consider:
a = 0
x = f(a++)
y = f(++a)
where function f(p) returns p + 1
x will be 1 (or 2)
y will be 2 (or 1)
And therein lies the problem. Did the author of the compiler pass the parameter after retrieval, after use, or after storage.
Generally, just use x = x + 1. It's way simpler.
Yes.
public class IncrementTest extends TestCase {
public void testPreIncrement() throws Exception {
int i = 0;
int j = i++;
assertEquals(0, j);
assertEquals(1, i);
}
public void testPostIncrement() throws Exception {
int i = 0;
int j = ++i;
assertEquals(1, j);
assertEquals(1, i);
}
}
Yes, using ++X, X+1 will be used in the expression. Using X++, X will be used in the expression and X will only be increased after the expression has been evaluated.
So if X = 9, using ++X, the value 10 will be used, else, the value 9.
If it's like many other languages you may want to have a simple try:
i = 0;
if (0 == i++) // if true, increment happened after equality check
if (2 == ++i) // if true, increment happened before equality check
If the above doesn't happen like that, they may be equivalent
Yes, the value returned is the value after and before the incrementation, respectively.
class Foo {
public static void main(String args[]) {
int x = 1;
int a = x++;
System.out.println("a is now " + a);
x = 1;
a = ++x;
System.out.println("a is now " + a);
}
}
$ java Foo
a is now 1
a is now 2
OK, I landed here because I recently came across the same issue when checking the classic stack implementation. Just a reminder that this is used in the array based implementation of Stack, which is a bit faster than the linked-list one.
Code below, check the push and pop func.
public class FixedCapacityStackOfStrings
{
private String[] s;
private int N=0;
public FixedCapacityStackOfStrings(int capacity)
{ s = new String[capacity];}
public boolean isEmpty()
{ return N == 0;}
public void push(String item)
{ s[N++] = item; }
public String pop()
{
String item = s[--N];
s[N] = null;
return item;
}
}
Yes, there is a difference, incase of x++(postincrement), value of x will be used in the expression and x will be incremented by 1 after the expression has been evaluated, on the other hand ++x(preincrement), x+1 will be used in the expression.
Take an example:
public static void main(String args[])
{
int i , j , k = 0;
j = k++; // Value of j is 0
i = ++j; // Value of i becomes 1
k = i++; // Value of k is 1
System.out.println(k);
}
The Question is already answered, but allow me to add from my side too.
First of all ++ means increment by one and -- means decrement by one.
Now x++ means Increment x after this line and ++x means Increment x before this line.
Check this Example
class Example {
public static void main (String args[]) {
int x=17,a,b;
a=x++;
b=++x;
System.out.println(“x=” + x +“a=” +a);
System.out.println(“x=” + x + “b=” +b);
a = x--;
b = --x;
System.out.println(“x=” + x + “a=” +a);
System.out.println(“x=” + x + “b=” +b);
}
}
It will give the following output:
x=19 a=17
x=19 b=19
x=18 a=19
x=17 b=17
public static void main(String[] args) {
int a = 1;
int b = a++; // this means b = whatever value a has but, I want to
increment a by 1
System.out.println("a is --> " + a); //2
System.out.println("b is --> " + b); //1
a = 1;
b = ++a; // this means b = a+1
System.out.println("now a is still --> " + a); //2
System.out.println("but b is --> " + b); //2
}
With i++, it's called postincrement, and the value is used in whatever context then incremented; ++i is preincrement increments the value first and then uses it in context.
If you're not using it in any context, it doesn't matter what you use, but postincrement is used by convention.
There is a huge difference.
As most of the answers have already pointed out the theory, I would like to point out an easy example:
int x = 1;
//would print 1 as first statement will x = x and then x will increase
int x = x++;
System.out.println(x);
Now let's see ++x:
int x = 1;
//would print 2 as first statement will increment x and then x will be stored
int x = ++x;
System.out.println(x);
Try to look at it this way:
from left to right do what you encounter first. If you see the x first, then that value is going to be used in evaluating the currently processing expression, if you see the increment (++) first, then add one to the current value of the variable and continue with the evaluation of the expression. Simple

Categories