Use of postfix/prefix expressions - java

I understand in prefix/postfix, there is no need to bother about precedence of operators.
But where do we use prefix/postfix expressions?
Are they internally converted by the compiler?
Is there a way I could write expression in prefix/postfix and the compiler evaluates it for me?

EDIT: Ff you're actually talking about postfix (RPN) notation, then no, the compiler uses infix notation for expressions. You could write an algorithm that converts an RPN expression into an infix expression, try this
Postfix and prefix operators are just like a binary operator, but they work on only one operand.
Postfix increment (the increment occurs after the variable is evaluated):
int x = 1;
int y = x++; // y = 1 but after the assignment occurs x = 2
int z = x; // z = 2
Prefix increment:
int x = 1;
int y = ++x; // y = 2 and before the assignment occurs x = 2
int z = x; // z = 2
The rules that apply to the increment operator also apply to the decrement operator.
Prefix NOT (inverts a boolean expression):
boolean a = true;
boolean b = !a; // b = false, a = true
I think I have understood the question correctly, but I'm not sure what you mean about the compiler "evaluating" them "for you".

I suspect that prefix and postfix operations and notations are mostly useful for theories these days, but they have been used "for real". See e.g. https://en.wikipedia.org/wiki/Stack_machine, https://en.wikipedia.org/wiki/Forth_%28programming_language%29, http://linux.about.com/library/cmd/blcmdl1_dc.htm, and https://en.wikipedia.org/wiki/Reverse_Polish_notation#Hewlett-Packard

Few languages use postfix notation (the only one I know of would be PostScript), but the resulting CPU instructions would be the same as for infix notation:
a = (3 + 4) * 5
or
a = * + 3 4 5
Would be converted (in an imaginary, very simple, instruction sets):
add r0 3 4 # r0 = 3 + 4
mul r1 r0 5 # r1 = r0 * 5
Your CPU does not care about the initial notation, all it accepts is a set of « basic » instructions, so the compiler has to convert the notation you use to instructions understandable by your CPU.

Related

Java post-increment and pre increment behaviour

I have a simple Java expression depicted below. Based on Operator Precedence table, I expect that this expression would return division by zero exception (since post-fix increment operator has highest priority) and expect that resulting expression would look like:
2 + 2 + 5 / 0
But result is 7, why ? (By little bit of experimentation I found that all operators are assigned value of 1 for some reason, but this does not make sense to me in case priority table is correct)
int intCountOperator = 0;
unaryOperand = ++intCountOperator + intCountOperator + 5 / intCountOperator++;
System.out.println(unaryOperand); // Prints 7
The operator precedence does not control the evaluation order. It controls only how the expression is to be read. For example, since multiplication has a higher precedence than addition, x + y * z is read as x + (y * z), not (x + y) * z. However, it does not change that first x is evaluated, then y and finally z.
Giving a good example with ++ and -- is more difficult, because there is usually only one reading which makes sense. However, you might notice that y - x++ compiles without error (if x and y are numerical variables). If ++ would have had a lower precedence than - it would be evaluated as (x - y)++ which would not compile.
Because of operator precedence, your expression is evaluated as:
(++intCountOperator) + (intCountOperator + (5 / (intCountOperator++)));
but the evaluation order is not changed by it.
The expression is evaluated from left to right :
unaryOperand = ++intCountOperator + intCountOperator + 5 / intCountOperator++;
1 + 1 + 5 / 1 = 7
Note that the operators are evaluated in the order you expect, i.e. 1 + 1 + (5/1) = 1 + 1 + 5 = 7, but the operands of all those expressions are evaluated from left to right.
The order of evaluation is from left to right and not right to left. So the result 7 which you are getting is correct.
unaryOperand = ++intCountOperator + intCountOperator + 5 / intCountOperator++;
is actually
unaryOperand = 1 + 1 + 5 / 1; = 7

operation on post++ and --pre operator

I am wondering with post and pre increment and decrement operation.
what I know in Java precedence of post operator is high and associativity is left-to-right.while associativity of pre operator is right-to-left
Oracle Java Tutorial
but my code showing me undesired result-
public class Bunnies {
static int count = 3;
public static void main(String[] args) {
System.out.println(--count*count++*count++);//out put is 12 expected 48
//associativity of post is higher so should be evaluated like this-
//--count*3**count++ count is 4 now
//--count*3*4 count is 5 now
//4*3*4=48
count = 3;
System.out.println(--count*++count*++count); //out put is 24 expected 120
//associativity of pre is right to left so should be evaluated like this-
//--count*++count*4 count is 4 now
//--count*5*4 count is 5 now
//4*5*4=120
count = 3;
System.out.println(-- count*count++);// out put is 4 expected 9
//--count*3 count is 4 now
//3*3=9
}
}
Order of evaluation of subexpressions is independent of both associativity and precedence.
The subexpression of the multiplication are evaluated from left to right, so when doing --count*count++*count++, you evaluate --count then count++ and finally count++.
And as the pre operator is evaluated first, --count will be decremented before its evaluation. In the same way, as the post operator is evaluated lately, count++ will be incremented after its evaluation.
The precedence only help the compiler to create a correct abstract syntactic tree.
For example, when doing ++count*2, the compiler use the precedence to know the expression is (++count)*2 and not ++(count*2). In the same way, when doing ++count*count--, the expression is (++count)*(count--) and not (++(count * count))-- or whatever. But then, during the evaluation of the multiplication ++count is evaluated before count--.
Hope this help you :)
I just found a great answer about expression evaluation in C# and Java here, enjoy :)
System.out.println(--count*count++*count++);
= 2 * 2 * 3 = 12
count = 3;
System.out.println(--count*++count*++count)
= 2*3*4 = 24
count = 3;
System.out.println(-- count*count++);
= 2 * 2 = 4
Pre increment/decrement
++/-- X first increments/decrements then does the operation.
Post increment/decrement
X ++/-- first the operation is done, then increment / decrement.
I take the first one.
System.out.println(--count*count++*count++);//out put is 12 expected 48
2 * 2 * 3 = 12
pre * post * post
count = 3:
Example 1:
--count*count++*count++ equals (--count)*(count++)*(count++)
(--count) = 2
(count++) = 2 (you increment it AFTER you do something with it)
(count++) = 3 ... count was incremented from before
2*2*3 = 12
Example 2:
--count*++count*++count equals (--count)*(++count)*(++count)
--count = 2
++count = 3
2 * 3 * 3 = 24
Example 3:
(--count)*(count++)
--count = 2
2 * 2 (the count++ gets changed afterwards)
Keep in mind that you have to watch the multiplicaton operator

Why is the operator precedence not followed here? [duplicate]

This question already has answers here:
What are the rules for evaluation order in Java?
(5 answers)
If parenthesis has a higher precedence then why is increment operator solved first?
(5 answers)
Closed 7 years ago.
In this code:
int y = 10;
int z = (++y * (y++ + 5));
What I expected
First y++ + 5 will be executed because of the precedence of the innermost parentheses. So value of y will be 11 and the value of this expression will be 15. Then ++y * () will be executed. So 12 * 15 = 180. So z=180
What I got
z=176
This means that the VM is going from left to right not following operator precedence. So is my understanding of operator precedence wrong?
The expression (++y * (y++ + 5)); will be placed in a stack something like this:
1. [++y]
2. [operation: *]
3. [y++ + 5] // grouped because of the parenthesis
And it will be executed in that order, as result
1. 10+1 = [11] // y incremented
2. [operation: *]
3. 11+5 = [16] // y will only increment after this operation
The the expression is evaluated as
11 * 16 = 176
First y++ + 5 will be executed because of the precedence of the innermost parentheses
Precedence and evaluation order are not the same thing. All binary expressions except the assignment expression are evaluated left-to-right. Therefore y++ is evaluated before the parenthesized expression on the right.
The parentheses just describe how the sub-expressions will be grouped together. Parenthesizing doesn't mean it will be evaluated first. Rather, the rule in java is evaluate each sub-expression strictly from left to right.
Always remember that the order of evaluation has absolutely nothing to do with operator precedence and associativity.
Java Oracle documentation says that:
15.7. Evaluation Order
The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.
Therefore, the expression (++y * (y++ + 5)) will be evaluated as
temp1 = ++y = 11
temp2 = y++ + 5 = 11 + 5 = 16
z = temp1*temp2 = 11*16 = 176
Further reading: Eric Lippert's blog, Precedence vs Associativity vs Order, explained in detailed about precedence, associativity and order of evaluation. Though this blog addresses c# but equally valid for java too.
First will be executed ++y. y will be 11.
Then will be executed y + 5 (actually y++ + 5 can be written as 5 + y++ which is interpreted as (5 + y) and then y++). z will become 11 * 16 = 176.
y will be 12 after the calculation finishes.
The calculation is going on following order
z= (++10 * (10++ + 5))
z= (11 * (11 + 5))//++ (prefix or postfix) has higher precedence than + or *
z= (11 * 16)
z= 176

x = x++ doesn't increment because the ++ is applied after the assignment?

From page 280 of OCP Java SE 6 Programmer Practice Exams, question 9:
int x = 3;
x = x++;
// x is still 3
In the explanation we can read that:
The x = x++; line doesn't leave x == 4 because the ++ is applied
after the assignment has occurred.
I agree that x is 3, I understand post-incremenation.
I don't agree with the explanation. I would replace "after" with "before".
I thought it works like this:
x is 3.
x++ is executed. I see this post-increment operator as a function:
int operator++() {
int temp = getX();
setX(temp + 1);
return temp;
}
So, after x++ execution, x is 4, but the value returned from x++ expression is 3.
Now, the assignment =. Simply write returned 3 to x.
So, in my eyes ++ is applied before the assignment has occurred. Am I wrong?
...the ++ is applied after the assignment has occurred.
Okay, hold on. This is actually confusing and perhaps suggests an incorrect behavior.
You have the expression†:
x = ( x++ )
What happens is (JLS 15.26.1):
The expression on the left-hand side of the assignment x is evaluated (to produce a variable).
The expression on the right-hand side of the assignment ( x++ ) is evaluated (to produce a value).
The evaluation of the right-hand side is: x is post-incremented, and the result of the expression is the old value of x.
The variable on the left-hand side, x, is assigned the value produced by the evaluation of the right-hand side, which is the old value of x.
So the post-increment happens before the assignment.
(Therefore, as we know, the value of x after executing the statement x = x++; is the same as the value of x before executing the statement, which is 3.)
So, in my eyes ++ is applied before the assignment has occurred. Am I wrong?
You are right.
Technically, the way it is specified is that x++ is evaluated before its result is stored and during the evaluation of the assignment operator. So x++ can be interpreted as happening either before or during the assignment. Not after, so the book appears to be wrong either way.
Just for the heck of it, we may also look at some bytecode:
/* int x = 3; */
iconst_3 // push the constant 3 on to the stack : temp = 3
istore_0 // pop the stack and store in local variable 0 : x = temp
/* x = x++; */
iload_0 // push local variable 0 on to the stack : temp = x
iinc 0 1 // increment local variable 0 by 1 : x = x + 1
istore_0 // pop the stack and store in local variable 0 : x = temp
The iinc happens before the istore.
†: The parentheses have no effect on the evaluation, they are just there for clarity.
Reaching over to the official spec:
postfix ++ section: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2
assignment operator section: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.26.1
In terms of assignment, this is simple assignment, so we hit case 3:
First, the left-hand operand is evaluated to produce a variable -- x
no errors -> the right-hand operand is evaluated -- x++
"the value of the right-hand operand is converted to the type of the left-hand variable, is subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable"
So in step 2, the postfix operator should get resolved, and then in step 3, x gets assigned its original value again:
call: x = x++;
interframe: LHS is variable 'x'
interframe: RHS caches return value as 3
interframe: x is incremented to 4
interframe: RHS cached value '3' is returned for assignment
interframe: variable x is assigned value 3
call result: x = 3
So I think you're right in that the book is wrong, and it might be worth contacting the authors or publisher to have a correction published (or added to an errata page, etc)
x++ means "use x and then increment x."
You can also use ++x, which means "increment x and then use x."
More easily, however, you can simply do
x += 1;
++x is called preincrement while x++ is called postincrement.
int x = 3;
x = ++x;
exemple
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

Strange behaviour of the increment operators in Java?

I have to pieces of code:
int m = 4;
int result = 3 * (++m);
and
int m = 4;
int result = 3 * (m++);
After the execution m is 5 and result is 15 in the first case, but in the second case, m is also 5 but result is 12. Why is this the case? Shouldn't it be at least the same behaviour?
I'm specifically talking about the rules of precedence. I always thought that these rules state that parantheses have a higher precedence than unary operators. So why isn't the expression in the parantheses evaluated first?
No - because in the first case the result is 3 multiplied by "the value of m after it's incremented" whereas in the second case the result is 3 multiplied by "the initial value of m before it's incremented".
This is the normal difference between pre-increment ("increment, and the value of the expression is the value after the increment") and post-increment ("remember the original value, then increment; the value of the expression is the original one").
The difference is when the result is assigned to m.
In the first case you have basically (not what it really does, but helps to understand)...
int result = 3 * (m=m+1);
In the second case you have
int result = 3 * m; m = m +1;
This is the definition of the operators: m++ evaluates to m, then increments m. It's a "post-increment". Parentheses around it don't change the fact that the operator evaluates to the variable, and also increments it afterward.
Think of it as "increment and get" and "get and increment." For instance, see AtomicInteger, which has the methods incrementAndGet() and getAndIncrement().

Categories