Through Java operator precedence table:
'|' Logical OR operator has higher precedence than '&&' logical AND operator.
I checked above fact using following code
int y = 5;
int x = 2;
if( x++ > 2 && ++y > 2 | true )
; //do nothing
System.out.println("x = " + x + " y = " + y);
but above line giving output as -
x = 3 y = 5
showing that x++ is evaluating first.
Even I put parentheses at condition around |
if( x++ > 2 && (++y > 2 | true) )
;
But still I am getting the same output.
Why operator precedence not working in this case?
That's not the logical operator. That's the bitwise operator. It will evaluate everything - that is, it won't short circuit - and if anything flips that bit to 1, it'll stay at 1 until negated.
Here's how these statements would evaluate:
x++ > 2 && ++y > 2 || true -> true. We fail with the logical AND, but succeed with the logical OR. With short circuiting, we don't continue to evaluate any portion of the logical AND, since x > 2 is false.
x++ > 2 && (++y > 2 || true) -> false, since we will short-circut due to x > 2 not being true.
If you actually don't want the short circuit behavior, then use the bitwise AND as well, and you'll get your expected evaluation block.
x++ > 2 & ++y > 2 | true will still evaluate to true, but the values of x and y will change to 3 and 6, respectively.
| is the bitwise OR operator. You're looking for ||. It's similar, but differs in that it has higher precedence and does not apply short circuit evaluation.
I see what you're really asking now. You're wondering why if && has the least precedence, the rest of the statement isn't evaluated before finally coming to it. So in
x++ > 2 && ++y > 2 | true
it should evaluate x++ > 2, then ++y > 2 | true and finally apply &&. Well, the answer is that && applies short circuit evaluation. Sure, it can evaluation everything and then apply its effect, and that's what the bitwise operator does. However it doesn't because
if (a && b && ...)
is supposed to behave similarly to
if (a) {
if (b) {
...
}
}
Operator precedence is as you expect, however, the evaluation is terminated early because of the property of the operator. So going back to
x++ > 2 && ++y > 2 | true
We see that x++ > 2 is false, so ++y > 2 | true is not evaluated.
try this
if( x++ > 2 && ++y > 2 || true )
You are using bitwise operator not logical operator
Operators in java
Even if the operator | has higher precedence, the operator isn't even discovered at the point where the program checks if calculating the right-hand side (of &&) is necessary.
Consider the statement (true && true | true). This is how it is calculated:
Check (true && ...) to see if further operations are necessary, (which is the case).
Higher precedence: Perform the operation (true | true) -> true.
Lower precedence: Perform the operation (true && true) -> true.
In your case, since (x++ > 2) gives false, the right-hand side of && is never even touched.
Since whatever you place the braces , it will start from left to right because it in case of && , it is optimized to check first condition , it get false , then why to go to second condition , no matter braces are there ,secondly x++ will get executed , condition get false , so it is printing the same output but when you do let say using ||
class Test{
public static void main(String[] args) {
int x=2,y=5;
if( x++ > 2 || (++y > 2 | true) )
;
System.out.println(x +" "+y );
}
}
It will print 3 6 because || takes place , first condition get false but when it comes to second , ++y > 2 evaluated to true | between boolean values give output on basis of bitwise OR , true OR true is true .
The logical operators: (&& , ||, &, |, and ^) can be used only to evaluate two
boolean expressions.
The difference between && and & is that the && operator
won't bother testing the right operand if the left evaluates to false, because the
result of the && expression can never be true.
The difference between || and | is
that the || operator won't bother testing the right operand if the left evaluates to
true, because the result is already known to be true at that point.
Bitwise operators: (&, |, and ^) can also be called as "Bitwise" operators. Bitwise operators compare two variables bit by bit, and return a variable
whose bits have been set based on whether the two variables being compared had
respective bits that were either both "on" (&), one or the other "on" (|), or exactly
one "on" (^).
Related
I'm trying to determine the conditions under which the following expression, where a and b are properly declared boolean variables, evaluates to false:
(a && (b || !a)) == a && b
To me, it seems that this expression will always evaluate to true. If either a or b is false, both sides of the equality operator will evaluate to false. If a and b are both true, then both sides will evaluate to true. That's all the options, and it's the correct answer for my online homework. However, when I run this in IntelliJ CE with the Java 11 JVM, it seems like it prints false whenever b is false:
when a and b are both false, IntelliJ outputs false
I get the same output when b is false and a is true. Can someone explain where the fault in my logic is? Thank you very much.
I think it is giving == operation priority over &&
Try this -
(a && (b || !a)) == (a && b)
You code should be:
boolean c = (a && (b || !a)) == (a && b);
otherwise it is evaluated as:
boolean c = ((a && (b || !a)) == a) && b;
Boolean operations have equivalent mathematical operations (this is what the CPU is ultimately doing). You can use this method to check any equation to make sure that it is coming out how you expect.
It can help you quickly see if your boolean logic is correct for all cases.
Using your equation here is an example:
Replace "true" with 1 and "false" with 0. Replace && with * (as in multiplies) and || with + (as in add). ! does what you expect still. Then check equality
so
a*(b+!a) == a*b
Then when a = false (0) and b = false(0) we have
0*(0+1) == 0*0
or 0=0
Which is true.
We can keep going with the other options to check.
a=1, b=1
1*(1+0) == 1*1
or 1=1
again, true
a=1, b=0
1*(0+1) == 1*0
1*1=0?
Not correct (false).
With that last test, we can see that this equation does not always evaluate to true. Just like in math, boolean operations have an order of operations (as mentioned by many others), but I like using this method to make sure my equations are working as intended.
I'm a little confused about the result of the following code:
int x = 1;
x -= ((x += 1) << 1);
System.out.println(x);
It prints out -3, but I'd expected it to print out -2, because in my head the computation should go like this:
| Opearation | Returned | x |
+------------+----------+---+
| int x = 1; | - | 1 |
+------------+----------+---+
| (x += 1) | 2 | 2 |
+------------+----------+---+
| (2 << 1) | 4 | 2 |
+------------+----------+---+
| x -= 4; | - |-2 |
What am I missing here? Can somebody please explain to me what's going on?
Thanks!
JLS 15.26.2 says following, https://docs.oracle.com/javase/specs/jls/se9/html/jls-15.html#jls-15.26.2
If the left-hand operand expression is not an array access expression, then:
First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs.
Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
Otherwise, the result of the binary operation is converted to the type of the left-hand variable, 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 the original value of x, i.e. 1, is saved, then the RHS is evaluated. Therefore it's -3.
Unlike some other languages (looking at you, C++), the Java Language Specification guarantees that expression operands are evaluated left-to-right:
The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.
Let's unroll your compound statement:
x -= ((x += 1) << 1);
x = x - ((x = x + 1) << 1);
^
The x with the arrow is evaluated first, which means that the assignment that happens later within the expression doesn't affect the value (in this case, the JVM stack already has a 1 on it). The rest of the evaluation proceeds as you expect, but the final operation is 1 - 4 = -3.
Note that right after the statement above, the JLS also includes a note that absolutely applies here:
It is recommended that code not rely crucially on this specification. Code is usually clearer when each expression contains at most one side effect, as its outermost operation, and when code does not depend on exactly which exception arises as a consequence of the left-to-right evaluation of expressions.
Value of x (=1) is populated on the RHS of the expression before the sub-expression (x+=1) is processed hence leftmost x is substituted as 1 way before it is processed in x+=1 which results into 2. Hence it will be ...
x = 1 - ((x=1+1) << 1)
x = 1 - ((x=2) << 1)
x = 1 - (2 << 1)
x = 1 - 4
x = -3
Here x=2 results into 2 as assignment operator returns same value as assigned to the variable.
x -= ((x += 1) << 1);
x = x - ((x += 1) << 1);
= 1 - ((1 + 1) << 1);
= 1 - (2 << 1)
= 1 - 4
= -3
boolean riddle = !( 1 < 8 || (5 > 2 && 3 < 5));
boolean is a true or false.
! = not
|| = or
&& = and
but I still dont understand this syntax... can someone explain me what this syntax excactly does?
Just dissect it:
There are some comparisons such as
5 > 2 ... true
3 < 5 ... true
Those two are pulled together using &&; so true && true --> true
1 < 8 ... true
That one is or'ed to the rest; so we get true or true --> true
Finally, not (true) --> false
Long story short: if you don't understand the whole picture, break it down into the parts you understand; and then pull those together again.
Edit: and of course, the order I am using in my explanation isn't what happens in reality. There, 1 < 8 is evaluated first; and as that is true; and "true or X" is always true, the other comparisons are not even computed.
The not ! operator negates what it is in front of. In this case !() it will produce the opposite of the what is inside of the parenthesis.
the || or operator checks to see if one condition or the other is true. At least one must be true for the condition to return true.
Finally the && checks both sides of the conditional statement to see if they are both true, and both of them must be true to proceed.
boolean riddle = !( 1 < 8 || (5 > 2 && 3 < 5));
Let's parse it the way Java does :
boolean : Here comes a boolean, i.e. true or false.
riddle : The variable riddle is declared to be a boolean.
= : The boolean variable riddle is initialized with the expression on the right.
!(...) : It returns a boolean, the negation (=opposite) of the boolean inside of the parentheses.
Inside the parentheses is a bool1 || bool2 expression, where || is a "lazy OR" operator. If bool1 is true, there's no need to evaluate bool2.
bool1 is 1 < 8, which is true.
bool2 isn't evaluated
bool1 ||bool2 is true
!(...) is false
riddle is initialized with false
At no point in time are 5 > 2 or 3 < 5 evaluated. Eclipse warns that those 2 expressions are "dead code" and could be removed.
The whole expression could be :
boolean riddle = !( 1 < 8 || (5 > 2 && doSomethingVeryDangerous()));
the result would be the same and no method call would happen at all.
The problem that you have is that you initialize at the same time as you are checking if it's true or false. You cannot compare boolean with integer. If you want to do it then you need to solve it in another way by converting from one datatype to another, or involve another variable in your solution. The way you need to solve your syntax problem is by dividing it like this:
How you did it...
boolean riddle = !( 1 < 8 || (5 > 2 && 3 < 5));
How to potentially solve it...
boolean riddle;
"...some code to decide if riddle will be true or
false and assign it to the variable riddle..."
if (riddle == true){
"...do some code here...";
}
if (riddle == false){
"...do some code here...";
}
Or you can solve the problem by not using boolean as datatype and instead only use integers like this...
int riddle;
"...some code to decide what value riddle will
have and assign it to the variable riddle..."
if ( riddle < 8 && riddle > 1){
"...do some code here...";
}
This question already has answers here:
In Java, what are the boolean "order of operations"?
(6 answers)
Closed 7 years ago.
Is it logically the same to do the following:
if ( a || b || c || d)
vs
if ((a || b) || (c || d))
In other words, how does the order of the && and || operators work, left to right or right to left?
How about:
if ( a && b && c && d)
vs
if ((a && b) && (c && d))
A sequence of identical operators is evaluated left to right if left-associative, or right to left if right-associative. So for example
a || b || c
is the same as
(a || b) || c
Howver if you mix || and && then operator precedence takes over.
I would like to provide a detailed answer in order for you not only understand the Logical (AND) and (OR) but, also how the operators in general are evaluated and what are their order of precedence. There are many ways to evaluate multiple logical expressions.
The first step is to understand the truth table for OR and AND shown below (Source):
As shown above, for different values of x and y the X AND Y (X && Y) and X OR Y (X || Y) yield different values. If you pay attention below AND operation requires both X and Y to be true in order for the result to be true however in case of OR if either X or Y is true then the result is true.
You need to know the above table for AND and OR by heart.
If you wish to be able to evaluate multiple logical expressions (ANDs and ORs), De Morgen's law can help you how to do it using NOT operation.
The rules can be expressed in English as:
The negation of a conjunction is the disjunction of the negations. The
negation of a disjunction is the conjunction of the negations.
or informally as:
"not (A and B)" is the same as "(not A) or (not B)"
also,
"not (A or B)" is the same as "(not A) and (not B)".
Read more on De Morgen's law and how to evaluate multiple logical expressions using it in here and here.
Precedence of logical AND and OR are left to right. See below table (Source) and that should give you an idea which operators are right to left and which ones are left to right as well as order of their precedence for example () and [] has the highest precedence and assignments have the lowest precedence among operators. If you notice
back to your example
if ( a || b || c || d)
According to truth table there are 16 possible combinations starting from
a=true,b=true,c=true,d=true
...
...
...
a=false,b=false,c=false,d=false
As long as any of the a,b,c,d are true then outcome is true hence, out of 16 possible combinations 15 will be true and last one will be false because all a,b,c,d are false.
ON whether below is same as above? Yes.
if ((a || b) || (c || d))
The only difference between the 2 is that in the second one the brackets are evaluated first hence (a || b) is evaluated then ORd with evaluation result of (c || d) but. The same logic true for above is true here too. As long as one of a,b,c,d are true then outcome is true.
In regards to below, yes the two evaluate to same outcome.
if ( a && b && c && d)
vs
if ((a && b) && (c && d))
Same as above 16 possible combinations for different values for a,b,c,d. The only true outcome for the above is when all a,b,c,d are true. Hence only one true and another 15 false.
Both statement if ( a || b || c || d) and if ((a || b) || (c || d)) will return true if either of the variables is true.
And also statement if ( a && b && c && d) and if ((a && b) && (c && d)) will return true only if none of the variables is false.
Also evaluation is from left to right.
These are short-circuiting operators that operate left-to-right, meaning as soon as the logical value of the whole expression can't be changed by the remaining terms, execution halts. As soon as || hits a true, it stops and the whole thing is true, and as soon as && hits a false, it the whole thing is false. So even though these operators are theoretically associative and commutative, order and grouping does have a practical effect. In fact, it's common to do something like:
if (foo == null || foo.someProperty())
or
if (foo != null && foo.someProperty())
Both of these are guaranteed not to have a null pointer exception because if foo is null, the second one doesn't get evaluated.
I'm trying to build an array of prime numbers in Java.
if(c % 2 != 0 || c % 3 != 0 || c % 5 != 0) {
n.add(c);
}
But my program seems to ignore the condition and just adds every number to my list.
But if I just use one condition for example,
if(c % 2 != 0)
The code works perfectly in ignoring any number which is a multiple of 2. What am I missing here?
You need to use logical and (&&) instead of or(||), as you want all conditions to be true before adding.
With logical or, each condition is evaluated from left to right, until finding one that matches.
Your condition right now evaluates to true if the number is not divisible by any of (2,3,5). This holds for all numbers except multiples of (all of) 2, 3, and 5. Try logical and (&&) instead of logical or (||).