Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Operator Precedence

 
Larry Jones
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

This prints true,false,false
I'm stuck thinking it should print true,true,false
Since the '&&' has precedence over the '||' shouldn't they be evaluated first?
It seems (b && c) should evaluate first. b==true, so it would short-circut leaving c==false. This would leave (a || true). The left side would evaluate first, also short circuting. 'a' would be set to true, resulting in: true,true,false
Why doesn't the && seem to have precedence?
Thank you
 
Larry Jones
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Doco, but it is those short circut operators and the fact that the variable assignment statements may or may not occur, which gives the opportunity for some of them to remain false.
For example
boolean a;
boolean b;
if((a = true) || (b = true)){}
System.out.println( a + "," + b);
This prints: true,false
But back to my original example: I can't understand what is going on in the order of precedence.
Why does this happen:
( (a = true) || (b = true) ) && (c = true);
and not this:
(a = true) || ( (b = true) && (c = true) );
[ April 07, 2003: Message edited by: Larry Jones ]
[ April 07, 2003: Message edited by: Larry Jones ]
 
Michael Morris
Ranch Hand
Posts: 3451
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Larry,
It is because they are short-circuit operators that (b = true) and (c = true) are not evaluated. As soon as there is enough information to gurantee the result no further evaluation takes place. Even if you put another set of parenthises around the last two assignments ((b = true) && (c = true)) it will still short-circuit.
Michael Morris
 
Wirianto Djunaidi
Ranch Hand
Posts: 210
Ruby Ubuntu VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Larry,
Looks like you mixed up your question in last post.
I think you are asking why the statement was processed as:
(a = true) || ( (b==true) && (c==true) )
instead of:
( (b==true) && (c==true) ) || (a==true)
I was curious too, why it behave like that...
wonder if the Left-To-Right precedence is somwhere between the arithmetic logic and boolean logic.
 
Marilyn de Queiroz
Sheriff
Posts: 9066
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Some people may not remember that the static booleans are initialized to "false" by default. So if they are short-circuited, the "true" value will never be assigned.
 
Wirianto Djunaidi
Ranch Hand
Posts: 210
Ruby Ubuntu VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
We are quite aware about the default 'false' and the short circuit thing.
If you pay closer attention to Larry's original post, the question is the behavior of the code is parsing the statement pretty much left to right aka treating && and || with the same precedence.
And according to the documentation, shouldn't && has higher precendence over ||?
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
&& has higher precedence than ||, but the expression still evaluates left to right, as short-circuit operations require that the left-hand side of an expression be evaluated before the right. Look at it this way:
boolean x = (a = true) || (b = true) && (c = true);
is (thanks to precedence) exactly equivalent to
boolean x = (a = true) || ((b = true) && (c = true));
But this is still evaluated left to right. The compiler sees the || and says "I've got to evaluate the LHS before I do anything about evaluating the RHS". Since the LHS is true, the || short-circuits, and no further calculation is required or even allowed. x is set to false, and that's it.
IF the LHS had been false, the JVM would then have had to move on to the RHS and evaluate
((b = true) && (c = true))
which it would again do left to right: b = true evaluates to true, no short circuit, so now evaluate c = true, also true, so now x is set to true.
[ April 06, 2003: Message edited by: Jim Yingst ]
 
Wirianto Djunaidi
Ranch Hand
Posts: 210
Ruby Ubuntu VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Jim, thats clear it up for me. I guess I'm stuck at the notation that higher precedence should be evaluated first without looking at the overall picture.
 
Marilyn de Queiroz
Sheriff
Posts: 9066
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ryo Saeba:
We are quite aware about the default 'false' and the short circuit thing.


We, who? You mean you are quite aware of it. I was responding to the possible lack of knowledge from another poster in this thread. No need to be defensive. This is a forum for beginners. And nobody know how many people will read this thread in the future.

If you pay closer attention to Larry's original post, the question is the behavior of the code is parsing the statement pretty much left to right aka treating && and || with the same precedence.

I understood the original question. I chose not to address it at that point.
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wow! The crystal clear message I got from all this is never write code like that!
 
Larry Jones
Greenhorn
Posts: 24
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you everyone for your responses. I understand what is going on in the code now, but I would like to ask one more question: Can someone give me a simple example of a && operator being evaluated before the || operator? That is, in what situation does the && operator show it has higher precedence? I've tried many little programs, but the results seem to indicate that || and && have the same precedence and are evaluated from left to right.
 
Joel McNary
Bartender
Posts: 1840
Eclipse IDE Java Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Larry Jones:
Thank you everyone for your responses. I understand what is going on in the code now, but I would like to ask one more question: Can someone give me a simple example of a && operator being evaluated before the || operator? That is, in what situation does the && operator show it has higher precedence? I've tried many little programs, but the results seem to indicate that || and && have the same precedence and are evaluated from left to right.

precedence simply dictates how to place absent parentheses. Look at this:

This will print "true" because && has precedence over ||. a && b evaluates to false, and then the false || c resolves to true, so true is printed.
If the order of precedence were reversed (|| evaluates before &&), then false would be printed.
Logically, the statement would then reduce to a && false, but since it is evaluated left to right, it doen't actually do that. It has its answer right away and stops. If you reverse the statement:

you can see this in action. It would evaluate c || b to be true and then have to evaluate the resulting true && a, which is false.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[I composed this before I saw Joel's response, so consider this as an elabloration, not a correction.]
Precedence in Java never affects the order in which subcomponents of an expression are evaluated. Rather, it affects the manner and order in which the subcomponents are combined after they've been evaluated. And (before that) it can affect whether or not a given subexpression is evaluated at all.
[ April 09, 2003: Message edited by: Jim Yingst ]
 
Monisha Talwar
Ranch Hand
Posts: 102
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am still confused!
I have a question regarding this code that Joel gave:

This will print "true" because && has precedence over ||. a && b evaluates to false, and then the false || c resolves to true, so true is printed.

I tried running it and indeed it printed true, but I still did not understand how
I thought since a is false, the && will just short circuit and not go ahead with the rest of the evaluation...which should have resulted in result = false.
Why is && going ahead to evaluate the next operand when its LHS is already false?
Monisha.
 
Marilyn de Queiroz
Sheriff
Posts: 9066
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
boolean a = false;
boolean b = false;
boolean c = true;
boolean result;result = a && b || c;
System.out.println("Result: " + result);

Think of it as (a && b) || c

b is not evaluated, but a && b is false because a is false. Then the result of that expression is put on the left side of the || (equivalent to a || c) which is true because c is true.
 
Monisha Talwar
Ranch Hand
Posts: 102
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Marilyn...that helped
 
Joel McNary
Bartender
Posts: 1840
Eclipse IDE Java Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've been thinking about better examples, and this that I have one. I just needed another variable

Since && happens before ||, this will result in true, sing they are grouped:

(the (true && false is, of course, not evaluated)).
If || happened before &&, the statement would result in false:

In any respects, anytime I have logic like this, I use () so that it is crystal clear to other people reading my code what is going on (those other people include me six months down the road...)
 
Consider Paul's rocket mass heater.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic