I have an order of operations problem from a quiz and the explanation is not exactly helpful. Here is the code:
package com.udayan.oca;
public class Test {
public static void main(String [] args) {
int a = 2;
boolean res = false;
res = a++ == 2 || --a == 2 && --a == 2;
System.out.println(a);
}
}
It says it prints 3 which it does because I tested that but I do not understand how. Here is their explanation:
a++ == 2 || --a == 2 && --a == 2;
[Given expression]. (a++) == 2 || --a == 2 && --a == 2;
[Postfix has got higher precedence than other operators].
(a++) == 2 || (--a) == 2 && (--a) == 2;
[After postfix, precedence is given to prefix].
((a++) == 2) || ((--a) == 2) && ((--a) == 2);
[== has higher precedence over && and ||].
((a++) == 2) || (((--a) == 2) && ((--a) == 2));
[&& has higher precedence over ||].
Let's start solving it: ((a++) == 2) || (((--a) == 2) && ((--a) == 2));
[a=2, res=false].
(2 == 2) || (((--a) == 2) && ((--a) == 2));
[a=3, res=false]. true || (((--a) == 2) && ((--a) == 2));
[a=3, res=false].
|| is a short-circuit operator, hence no need to evaluate expression on the right.
res is true and a is 3.
Yes, I understand short circuiting by the way so no need to explain that.
So here is my thinking however:
res = a++ == 2 || --a == 2 && --a == 2 ->
(((a++) == 2) || (((--a) == 2) && ((--a) == 2))) [a = 2]
(((a++) == 2) || ((**1** == 2) && ((--a) == 2))) [a = 1]
(((a++) == 2) || (**false** && (**0** == 2))) [a = 1] //short-circuits
(((a++) == 2) || **false**) [a = 1] //short circuits
(**false**) [a = 1]
????
Another point is that the answer key says to do a++ first then || next. a++ yah that makes sense. But I thought && is before ||.
From the Java Language Specification,
The conditional-or operator || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false.
So, this is simpler than you think. res = a++ == 2 || --a == 2 && --a == 2; is evaluated like so:
res = ((a++ == 2) || ((--a == 2) && (--a == 2)));
a++ == 2? Post-increment means that a is read as 2. Then that expression is evaluated. 2 == 2, which is true. Short circuit means that the rest of the expression is never evaluated.
So, essentially all the above code does is res = a++ == 2;
I made a simple program to test this:
public class TestSOCode {
public static void main(String [] args) {
test1();
}
private static void test1(){
int a = 2;
boolean res = false;
//res = a++ == 2 || --a == 2 && --a == 2;
res = expression(a++, "One") || expression(--a, "Two") && expression(--a, "Three");
System.out.println(res +" "+ a);
}
private static boolean expression(int i, String s){
System.out.println(s+ " called with "+ i);
return i == 2;
}
}
This gives the result
One called with 2
true 3
UPDATE: After some discussion and research, I think there's been a misunderstanding of the difference between precedence and execution order when it comes to logical operators.
res = a++ == 2 || --a == 2 && --a == 2;
The above statement's precedence is worked out before it's evaluated. I won't go over the other precedence rules since it would complicate this answer, so I'll simplify it:
res = x || y && z;
&& takes precedence, so the expressions are grouped together like so:
res = x || (y && z);
As we can see, && takes priority, so the expressions to it's left and right are grouped together, then || is evalutated. The expression to it's left is x and the expression on it's right is (y && z) (I think we were both thinking that if && took priority, it would be like (a || b) && c so it would be evaluated first, but that's not how it works). If we want to see that this is in fact the case, we can modify the above code like so:
res = expression(a = 8, "One") || expression(a = 16, "Two") && expression(a = 32, "Three");
This is equivalent to false || (false && false), but without any compiler interference with compile-time constants. The result of this is:
One called with 8
Two called with 16
false 16
First, the || is evaluated, then the left side of the &&. This returns false, and false && ? will always be false, so the third expression is not evaluated. But no precedence rules have been violated. I hope this has cleared up any confusion. If not, I'm happy to continue discussion in chat and update my answer. Because we know from the original code that if the first expression is true, the || returns true and short-circuits, we can say that a || b && c is not grouped together into (a || b) && c.
res = a++ == 2 || --a == 2 && --a == 2 (res is true)
1. a++ (post-increment, no) -> a = a + 1 -> it's still 2 -> when true -> it becomes 3
2. --a (pre-increment, right to left) -> a - 1 = a -> 1
3. --a (pre-increment, right to left) -> a - 1 = a -> 0 (its because of logical and, it never execute this part)
4. == (equality, left to right) -> 2 == 2 || 1 == 2 && 0 == 2 -> true || false && false
5. && (logical and, left to right) -> false -> no more steps
6. || (logical or, left to right) -> true -> go to 1.
// so take 3
// moral of the story is always use paranthesis
// op is correct for short-circuit
In the end when(((a++) == 2) || false) [a = 1]
Is done then as the || operator having less precedence than ++ so here a will become 3 .. then it will print a=3
Though it's a short circuit operator still it have to do the ++ operator 1st.
Related
So my counter is supposed to not count +1 for the string ":DD" that's why I wrote that only if the length of my string is 2 the counter should add +1. But it adds +1 although the string length is 3. Why is that?
P.S.: I've put length() <=3 in the first if statement, for another else if that comes after the 2nd if statement.
int counter = 0;
String tgt = ":DD";
for (int i = 0; i < a.size(); i++) {
if (tgt.length() <= 3 && tgt.charAt(0) == ':' || tgt.charAt(0) == ';') {
if (tgt.length() == 2 &&
tgt.charAt(1) == ')' || tgt.charAt(1) == 'D') {
counter += 1;
}
}
}
The && operator has higher precedence than ||, messing up your intended logic.
The Java operators page lists Java operators in order of precedence.
Because of this, it's as if parentheses are around the two && operands:
if ((tgt.length() <= 3 && tgt.charAt(0) == ':') || tgt.charAt(0) == ';')
{
if ((tgt.length() == 2 && tgt.charAt(1) == ')') || tgt.charAt(1) == 'D')
In the second if condition, the && may return false, but the second (index 1) character is 'D', so the whole condition is true and your counter gets updated.
Place explicit parentheses around your || operands, which is what I think you intended.
if (tgt.length() <= 3 && (tgt.charAt(0) == ':' || tgt.charAt(0) == ';'))
{
if (tgt.length() == 2 && (tgt.charAt(1) == ')' || tgt.charAt(1) == 'D'))
This is a case operator precedence (source: oracle.com) not matching with the expectations we as developers might have. The &&-operator has a higher precedence than ||. This means that
tgt.length() <= 3 && tgt.charAt(0) == ':' || tgt.charAt(0) == ';'
evaluates to the same value as
(tgt.length() <= 3 && tgt.charAt(0) == ':') || tgt.charAt(0) == ';'
(Notice the parentheses around (... && ...))
If we want that the ||-operator is evaluated first, we have to add explicit parentheses:
tgt.length() <= 3 && (tgt.charAt(0) == ':' || tgt.charAt(0) == ';')
(Notice the parentheses around (... || ...))
(likewise with the 2nd if-condition)
Ideone demo
The problem seems to be that your second if isn't correctly set.
If I understand correctly you want to check if the second letter is a ")" or a "D" unless the length is of two.
what your checking is if it's length = 2 and 2nd letter ")" OR that the second letter is simply equal to a "D"
you would fix it by changing the if to if ((&& tgt.charAt(1) == ')'|| tgt.charAt(1) == 'D') && tgt.length() != 2) {
Currently I am working on a little personal project to help myself learn about coding.
I'm wondering for future reference if I can combine logical operators of different types in a single if statement.
For example if I had
if (n == 0 || n == 1 && m == 0 || m == 1) {
doSomething();
}
Would it check if either parts of the left side are true, then if either parts of the right are true, or would it do something similar to checking if both of the middle ones are true?
Does using parenthesis change anything
For example
if ((n == 0 || n == 1) && (m == 0 || m == 1)) {
doSomething();
}
Edit:
From a suggestion I tried it out, but when i put three variables it started acting weird
Here's my test:
int n = 1;
int m = 1;
int o = 1;
if (n == 0 || n == 1 && m == 0 || m == 1 && o == 0 || o == 1) {
System.out.println("True");
}
else {
System.out.println("False");
}
if ((n == 0 || n == 1) && (m == 0 || m == 1) && (o == 0 || o == 1)) {
System.out.println("True");
}
else {
System.out.println("False");
}
if all of them are 1 or 0, they both evaluate true, if n or m is not 1 or 0 the top evaluates true but the bottom does not.
However if o is not 0 or 1 both of them are false.
I have found that parenthesis do in fact make a difference, but I can't quite tell why it's acting the way it is.
&& has a higher precedence then ||, so n == 0 || n == 1 && m == 0 || m == 1 equals n == 0 || (n == 1 && m == 0) || m == 1. You may check the precedence table here.
So everywhere I look, it says that && is evaluated first, then || is evaluated second. So either I am doing something wrong or it is wrong. Here's the code:
static boolean foo(boolean b, int id){ System.out.println(id); return b;}
static{ System.out.println(foo(true, 3) && foo(true, 1) || foo(false, 2)) }
//returns 3 1
static{ System.out.println(foo(true, 2) || foo(true, 3) && foo(true, 1)}
//returns 2
In the first static block, && goes first, short circuits and ignores the || but in the second static block which is simply the reverse, || goes first and ignored the &&. This demonstrates left to right but according to the java doc, && has higher precedence which means && should always go first.
Some documents about precedence (logical and is higher than or):
1. https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
2. https://chortle.ccsu.edu/Java5/Notes/chap40/ch40_16.html
3. http://www.cs.bilkent.edu.tr/~guvenir/courses/CS101/op_precedence.html
...
Higher predecence of && just means that
foo(true, 2) || foo(true, 3) && foo(true, 1)
is the same as
foo(true, 2) || (foo(true, 3) && foo(true, 1))
but not
(foo(true, 2) || foo(true, 3)) && foo(true, 1)
Nothing else. It doesn't imply anything about evaluation order.
Now, for most operators, evaluating x op y requires evaluating both x and y. If || was one of them, it would be the same as (return is from evaluating ||, not from the entire method)
boolean tmp1 = foo(true, 2);
boolean tmp2 = foo(true, 3) && foo(true, 1);
return tmp1 || tmp2;
and && would indeed "go first". But there are three operators which don't work like that: &&, || and ?:. Instead you get
boolean tmp1 = foo(true, 2);
if (tmp1) {
return true;
} else {
return foo(true, 3) && foo(true, 1);
}
I have a conditional if statement like this
if ((a && (b || c)) ||
(b && (a || c))) {
}
basically what I'm trying to achieve is that I can only have one option true, but two is not ok!
Can it be more simplified, looks redundant to me!
Or should I extract it to a function?
edit
if (a && !b && !c) // process a
if (b && !a && !c) // process b
if (c && !a && !b) // process c
if (!a && !b && c!) // none present exception
else {} // more than one case exception
Yes it can be simpler, this would be more than enough since a && b will give the same result as b && a:
if (a && b || c) {
}
Note: the original question was completely different, and asked to simplify the following expression:
if ((a && b || c) ||
(b && a || c)) {
}
Following the comment and the edit, each line is the development of the previous one:
(a && (b || c)) || (b && (a || c))
((a && b) || (a && c)) || ((a && b) || (b && c))
(a && b) || (a && c) || (a && b) || (b && c)
You have a duplicate, so you can turn it to: (those lines are equals)
(a && b) || (a && c) || (b && c)
(a && (b ||c)) || (b&&c)
&& operator is Commutative so a && b or b && a results in same output.
Now your condition becomes like this
if ((a && b || c) ||
(a && b || c)) {
}
|| operator is Idempotent so x || x results x
your expression becomes (a && b) || c
But in java && and || operators exhibit "short-circuiting" behavior
First operand will be evaluated first and then second operand will be evaluated only if need so you can choose which operand to keep first based on operand complexity.
if (c || (a && b) {
...
}
The 2 large conditions are the same... ´&&` is commutative
First question, I'm trying to do a practice where I am asked to return true if the given non-negative number is a multiple of 3 or 5, but not both. Examples are;
old35(3) → true
old35(10) → true
old35(15) → false
So 3 would be true, as it's a multiple of 3, but I can't currently make my code work for all instances. Code below;
public boolean old35(int n) {
if ((35 % n == 3) || (35 % n == 5))
return true;
return false;
}
How could I edit this to fit the criteria of what the practice is telling me to do?
>
I will throw a detailed explanation. First, you use the remainder sign to check the condition where remainder is zero;
n % 3 == 0
and
n % 5 == 0
Then for a one to one translation for your conditions, put them together as:
((n % 3 == 0) || (n % 5 == 0)) // Multiple of 3 or 5
!((n % 3 == 0) && (n % 5 == 0)) // But not both
Add (and) them together;
public static boolean old35(int n) {
return(((n % 3 == 0) || (n % 5 == 0)) && !((n % 3 == 0) && (n % 5 == 0)));
}
But simply, what you are doing is the XOR (^) operation, the following code is valid and simple:
public static boolean old35(int n) {
return((n % 3 == 0) ^ (n % 5 == 0));
}
You can use the logical XOR of the conditions. Basically you can do C1 ^ C2.
Edit: To check if multiple of 3 you must check n % 3 == 0, the same for multiple of 5.