nick woodward wrote:line 2:
This is what throws me. It is evaluating (a=false) and then short-circuiting both (b=true) and (c=true)...
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:
nick woodward wrote:line 2:
This is what throws me. It is evaluating (a=false) and then short-circuiting both (b=true) and (c=true)...
What is the precedence of '|'? Is it greater or less than or equal to '&&'?
From your answer you should be able to work out what's happening (and it's not what you describe).
BTW, you also have '=' in these examples, but since they're all inside parentheses they will always be evaluated first (if at all).
Winston
nick woodward wrote:It's less than isn't it?
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
nick woodward wrote:so line 2 isn't short circuiting b and c? i'm not sure how else line 1 evaluates to true, and line 2 to false!
Henry Wong wrote:The bitwise OR operator has higher precedence than the logical AND operator, so yes, b and c assignments has been short circuited.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
nick woodward wrote:this makes me think b | c is not evaluated and is treated as one operand (otherwise surely |(c=true) would be evaluate to true?)
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
nick woodward wrote:don't do that! don't disagree!
having said that, i'm annoyed with the princeton link:
http://introcs.cs.princeton.edu/java/11precedence/
which says | has a lower precedence than &&.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:
nick woodward wrote:don't do that! don't disagree!
I'm not disagreeing about the result; merely Henry's use of the term "short circuit".
having said that, i'm annoyed with the princeton link:
http://introcs.cs.princeton.edu/java/11precedence/
which says | has a lower precedence than &&.
That's not how I read it. In fact '|' is #11 and '&&' is #12.
Winston
Winston Gutkowski wrote:Either way the result is the same, but the way I'd assume it to work if these were variables with unknown values:..
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
nick woodward wrote:yup, that makes complete sense, thanks!
what a massive waste of time this afternoon was!!!
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
nick woodward wrote:line 1:
&& has precedence here, but i'm pretty sure precedence doesn't matter. order of operations does (left to right) in combination with left associativity.
so (a=false) is evaluated, (b=true) is short-circuited, and (c=true) evaluates to true (causing the entire expression to evaluate to true).
effectively (a=false) && (b=true) count as a single operand for || (c=true). or ((a=false) && (b=true)) || (c=true)
nick woodward wrote:Again, apologies for asking the same question again, especially after all the effort that went into the last thread, but this has had me going in circles for way too long now!!! I can't see it, even having read the thread(s). I must be missing something. I'm starting to consider 'a brain' may be the answer..!
nick woodward wrote:I would say that, in my humble but likely completely incorrect opinion, b|c is not evaluated, because evaluation is left to right regardless of precedence, and the compiler comes across the short-circuit &&. By the same logic I'd say that in line 1 only 2 assignments take place. how would it be 3? but as i said, i would not be surprise if i was wrong!
nick woodward wrote:also - was that Princeton link and table of precedence wrong? still looks it to me
Princeton | Oracle |
---|---|
[] . () ++ -- | expr++ expr-- |
++ -- + - ! ~ | ++expr --expr +expr -expr ~ ! |
() new | (not mentioned) |
* / % | * / % |
+ - + | + - |
<< >> >>> | << >> >>> |
< <= > >= instanceof | < > <= >= instanceof |
== != | == != |
& | & |
^ | ^ |
| | | |
&& | && |
|| | || |
?: | ? : |
= += -= *= /= %= &= ^= |= <<= >>= >>>= | = += -= *= /= %= &= ^= |= <<= >>= >>>= |
Roel De Nijs wrote:
nick woodward wrote:I would say that, in my humble but likely completely incorrect opinion, b|c is not evaluated, because evaluation is left to right regardless of precedence, and the compiler comes across the short-circuit &&. By the same logic I'd say that in line 1 only 2 assignments take place. how would it be 3? but as i said, i would not be surprise if i was wrong!
In line1 of the original code snippet you have two assignments: false is assigned to a and true is assigned to c. The assignment of b is not executed, which is proven by the output (otherwise its value had been true as well). You could of course argue that the result of the whole expression is assigned to the boolean parameter of the println method
nick woodward wrote:also - was that Princeton link and table of precedence wrong? still looks it to me
Honestly I don't see any difference between the Princeton table and the Oracle table, except the first one has more operators. Where do you see a difference between both tables? Here's a summary of both tables.
Princeton Oracle [] . () ++ -- expr++ expr-- ++ -- + - ! ~ ++expr --expr +expr -expr ~ ! () new (not mentioned) * / % * / % + - + + - << >> >>> << >> >>> < <= > >= instanceof < > <= >= instanceof == != == != & & ^ ^ | | && && || || ?: ? : = += -= *= /= %= &= ^= |= <<= >>= >>>= = += -= *= /= %= &= ^= |= <<= >>= >>>=
Hope it helps!
Kind regards,
Roel
nick woodward wrote:*** ah my brain must be fried. on the princeton table I was looking at '+' (concatenation) and wondering why addition came above multiplication. concatenation not appearing on the oracle list is where i think the confusion came in.....
nick woodward wrote:attempt 3 is my final answer, and i'm fairly confident, but this was actually a topic WAY up on my list of things to do. I'm TERRIBLE at doing these at any sort of speed, mainly because I don't have a good strategy for writing down the cycles and the values - i often lose track (clearly). maybe it's just practice, but I'm fairly sure poor technique has something to do with it too. any suggestions or good thread links? should probably make it a large section in your book Roel. (i'll go search the forum now :P)
nick woodward wrote:I would say that, in my humble but likely completely incorrect opinion, b|c is not evaluated, because evaluation is left to right regardless of precedence, and the compiler comes across the short-circuit &&. By the same logic I'd say that in line 1 only 2 assignments take place. how would it be 3? but as i said, i would not be surprise if i was wrong!
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:The problem is that you have two factors at work here. Modern compilers are very smart, so it's quite possible that it can look at an expression like
(a=false)
and say "you know what, I KNOW that evaluates to false, so I also know that anything to the right of '&&' is irrelevant, regardless of any stupid precedence rules".
Winston Gutkowski wrote:but what if the code was something like this?:
nick woodward wrote:the thing is, these sorts of questions are generally far more time consuming (for me) than their relative worth, so i'm thinking of skipping them and doing them all at the end. but i guess a massive amount of practice won't hurt
nick woodward wrote:Roel - I've got to massively improve my speed in general so that I get time at the end, but that's the idea/hope!
nick woodward wrote:but surely if that was the case Winston then the && would have very little benefit in terms of efficiency other than in the case that the assignments to a b and c were explicitly stated or known.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
nick woodward wrote:in case I forget the rule that seems to work for me:
that evaluation order != precedence
for the time being i'm just going to assume that the evaluating you're talking about (ie having the variables and input for the expression as a whole) is different to how the expression is actually evaluated at runtime.
i'm already starting to over-think it now......
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:evaluation order absolutely == precedence; and "short circuiting" (or ignoring) only takes place at the time that a short-circuiting operation is evaluated.
Winston Gutkowski wrote:The compiler has TWO functions:
1. To ensure that your syntax is correct.
2. To generate the bytecode to run your code.
and it's in that last requirement that modern compilers have a lot of latitude.
Winston Gutkowski wrote:Take your line 2 example:
If you look at it simply as a purist, you have three expressions enclosed in brackets, which has the highest precedence of all the operators in the expression; therefore, those 3 expressions should be evaluated first. Next you have the one sandwiching '|', which has the next highest priority, so it should be evaluated next. And finally you have the '&&'. The '='s are irrelevant because they have already been overridden by the enclosing '()'.
And if you look at it that way, you will get the correct result for the entire expression.
Roel De Nijs wrote:That's complete BS! And is already illustrated many times in this topic. Every code snippet in this topic using the | operator illustrates short-circuiting happens BEFORE precedence. If that would not have been the case, variables b and c would have been true, but both are (clearly) false as these subexpressions are NOT evaluated due to the short-circuit operator && (which has a lower precedence than the | operator)
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:And I'm pretty sure that the OCJP exam will assume my "purist" interpretation for all expressions, not just your line 2.
Roel De Nijs wrote:According to your "purist" interpretation, the expression args[0].equals("java") will be evaluated first...
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Roel De Nijs wrote:When 2 operators share an operand the operator with the higher precedence goes first. Little example: 2 + 3 * 4 is treated as 2 + (3 * 4) (as multiplification has higher precedence than addition).
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:So surely nick's expression should be dealt with as
false && (true | true)
But it isn't - presumably because in "left-to-right" evaluation, 'false &&' trumps all because of short-circuiting, whereas '2 +' is just "2 plus whatever" (which might already be evaluated).
Winston Gutkowski wrote:(*) Edit: That still sounds wrong, because the first expression can't be evaluated unless the '*' is processed before the '+'.
Roel De Nijs wrote:
Winston Gutkowski wrote:(*) Edit: That still sounds wrong, because the first expression can't be evaluated unless the '*' is processed before the '+'.
The epression 2 + 3 * 4 will be evaluated as 2 + (3 * 4). And that means first the 2 will be evaluated, then 3 * 4 will be evaluated and finally the sum 2 + 12 will be evaluated. If you would like to see some kind of evaluation flow, it would look like this
Roel De Nijs wrote:And to illustrate that the multiplication is not evaluated first, I have this "nice" example ...
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:
To me, short-circuiting changes everything, so it should be explained right at the start:
1. Evaluate lvalue.
2. Check if op allows "short-circuiting", and return the result if no more evaluation is necessary.
Otherwise:
3. Evaluate rvalue.
4. Apply op.
and forget all the other guff until you've explained that. I'd also put '? :' in a completely separate category, with back references.
Henry Wong wrote:I am not completely sure if I agree with this... I would argue that the compiler still need to "evaluate" the rvalue.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
They worship nothing. They say it's because nothing lasts forever. Like this tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
|