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);
}
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.
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.
if ((board[x][x] && board[x + 1][x + 1] && board[x + 2][x + 2]) == 'Y') {
playerWins = true;
}
Why can't I use && and || here?
You want this:
if (board[x][x] == 'Y' && board[x + 1][x + 1] == 'Y' && board[x + 2][x + 2] == 'Y') {
playerWins = true;
}
&& can only be used to join boolean expressions together.
Your code assumed some sort of distribution rule, like (x && y) == z being equivalent to (x == z) && (y == z). In English, you can state things that way "If x and y are both z," but programming languages (and formal logic) don't have such a definition.
Java logical operators perform operations on just boolean values. So the two operands of any logical operators need to be boolean. In your code, board[x][y] is of type char and so it throws an exception. You need to compare it to something or have something else which is boolean.
Same for board[x + 1][x + 1].
(Typed from phone)
Java's conditional evaluation is different compared to other languages (like C, C++).
Although loop conditions (if, while and the exit condition in for) in
Java and C++ both expect a boolean expression, code such as if(a = 5)
will cause a compile error in Java because there is no implicit
narrowing conversion from int to boolean.
Please refer the below link for details:
https://en.wikipedia.org/wiki/Comparison_of_Java_and_C%2B%2B
You cannot concatenate these expressions to be evaluated with '&&' or '||', since they will not be evaluated to boolean, but here in this case to chars.
However, you can do this:
if (board[x][x] == 'Y' && board[x + 1][x + 1] == 'Y' && board[x + 2][x + 2] == 'Y') {
playerWins = true;
}
or even this way:
/*so this methods check if the board has a different value than 'Y', so it returns false immediately without going over the other positions, otherwise if the value was equal to Y at all positions the if statement wont be accessed,
you will exit the for-loop & return true; You're main method must store the boolean value returned not more */
public static boolean winGame(PARAMS p) { //you can give it the 2d array as a parameter for example..
for(int x = 0; x < value; x++) { // you specify the value according to your board
if(board[x][x] != 'Y') {
return false;
}
return true;
}
I am working on making a coffee ordering system. It takes inputs from users and calculates the price of their coffee. One of the inputs asked for is "syrupshots". This code always makes syrupshots = 3 even if the user properly chose a number according to the size of their coffee.
//if size == tall syrup shots <=3
if(size == 1 && syrupshots < 1 || syrupshots > 3)
{
syrupshots = 3;
}
//else if size == medium syrup shots <=5
else if(size == 2 && syrupshots < 1 || syrupshots > 5)
{
syrupshots = 3;
}
//else if size == Venti syrup shots <=7
else if(size == 3 && syrupshots < 1 || syrupshots > 7)
{
syrupshots = 3;
}
System.out.println(syrupshots);
I am not sure why syrupshots is always = 3 no matter what.
Not always, sometimes it returns 1 or 2. But never >3, like it looks like it should.
Your problem is with logical operator precedence. For example:
if(size == 1 && syrupshots < 1 || syrupshots > 3) {}
If size=3 and syrupshots=5 (a valid combination), then this if block is still entered because the && is evaluated first:
size == 1 && syrupshots < 1
and that equals false, so you have left (false || syrupshots > 3)
BUT then the || is evaluated, syrupshots > 3 is true, so the whole expression is true
You need to change the order of precedence by using brackets:
if(size == 1 && (syrupshots < 1 || syrupshots > 3)) {}
As one comment says, all conditions trigger syrupshots to be assigned three. Also, I don't think you wrote your test condiiotns correctly, judging from your comments.
if(size == 1 && syrupshots <= 3)
^That would be proper way to test for the check outlined in your comment