Order of short circuit evaluation and prefix increment operators - java

When evaluating a Boolean expression in java, I find myself a bit bewildered by short circuit evaluation and pre-fix increment operators. Consider the following:
int e=20;
int f=25;
if(++e>21 || ++e>21 && f>30){
System.out.println("Hi");
}
System.out.println(e);
I understand that if ++e were greater than 21, the rest of the IF statement would skip over (due to short circuit eval). But in this case, it doesn't, as the first part is not true, so we move on to the AND statement. At this point, is e still 20? Or during the short circuit eval, did it go up to 21?
Well, I am assuming at this point, we evaluate the AND statement (as we normally do before OR), we add 1 to e, which I assume becomes 21 now? It is false, and therefore the entire AND statement is false.
Do we, at this point, go BACK and do the OR statement? Since it comes after AND? Shouldn't e be pumped up to 22 now? And since it's an OR statement, it should come out to TRUE OR FALSE, which should be TRUE, and "Hi" should appear on the screen. But it doesn't.
Weirdly, the value for e is 22 when the code finishes. 22 is the value we needed for the IF statement to be true, but the condition inside didn't run.
I am extremely confused.

Let's unwind what short-circuiting actually is!
int e=20;
int f=25;
if((++e>21) || (++e>21 && f>30)){
System.out.println("Hi");
}
System.out.println(e);
So, if that left hand side of the or condition evaluates to true, we don't need to do anything more, so let's be more explicit about that:
int e=20;
int f=25;
if (++e > 21)
{
System.out.println("Hi");
}
// the or becomes an else if, if the first condition fails then we check the second
else if (++e>21 && f>30)
{
System.out.println("Hi");
}
System.out.println(e);
Now, let's be more explicit about when that first increment happens:
int e=20;
int f=25;
e += 1;
if (e > 21) // e = 21, 21 is not > 21
{
System.out.println("Hi");
}
// We need to test this condition, as you've said
// e is still 21
else if (++e>21 && f>30)
{
System.out.println("Hi");
}
System.out.println(e);
Again, let's unwind what and means in terms of short-circuiting
int e=20;
int f=25;
e += 1;
if (e > 21) // e = 21, 21 is not > 21
{
System.out.println("Hi");
}
// We need to test this condition, as you've said
// e is still 21
else if (++e > 21) // the and becomes a nested if, first the left must be true before we test the right
{
if (f > 30)
{
System.out.println("Hi");
}
}
System.out.println(e);
And again, let's be explicit about that increment!
int e=20;
int f=25;
e += 1;
if (e > 21) // e = 21, 21 is not > 21
{
System.out.println("Hi");
}
// We need to test this condition, as you've said
// e is still 21
else
{
e += 1;
if (e > 21) // e is now 22, this condition succeeds
{
if (f > 30) // f is not >30, this condition fails!
{
System.out.println("Hi");
}
}
// e is still 22
}
// e is still 22
System.out.println(e);
Hopefully this makes it all clear!
EDIT: Actually, having re-read your question a couple of times, it appears you are getting confused with the precedence of the logical operators. You seem to think that the and should execute before the or right? presumably because and has the higher precedence. All that means, however, is that the implicit brackets go round the and first like so;
p || q && r == p || (q && r)
You should be able to see that in this form, the outside or must be evaluated first, before the and is. We always evaluate left to right!

Related

Displays if a whole number (>0) is divisible by 2 and 3

I have tried to do this in java however the && symbols keep on giving error.
Below is the code that I used:
int d = 18;
{
if ((d % 2) && (d% 3));
{
System.out.println("True!");
}
{
System.out.println("False!");
}
}
This is my code. I am not sure why its not working. Thanks
The error message is The operator && is undefined for the argument type(s) int, int. #
I have got it to work now. I have an else error . "The error says Syntax error on token "else", delete this token"
public class CS1702_Lab3_4 {
int d = 18;
{
if ((d % 2 == 0) && (d % 3 == 0));
{
System.out.println("True!");
}
else
{
System.out.println("False");
}
}
}
Also when I add an else it says Syntax error on token "else", delete this token
Please learn about the modulus operator, and how to check divisibility in java.
if ((d % 2 == 0) && (d % 3 == 0))
{
System.out.println("True!");
}
Also, you had a rogue semi-colon at the end of your if statement.
EDIT: Fixed code
public class CS1702_Lab3_4 {
public static void main(String[] args) { // Entry into our program
int d = 18;
if ((d % 2 == 0) && (d % 3 == 0)) {
System.out.println("Divisible!");
} else {
System.out.println("Not divisible!");
}
}
}
I'd recommend looking at some basic Java tutorials, however the fixes I applied included:
Contained your code inside of a method, specifically the main method, which is the entry point to a runnable Java application. Java is not a procedural language, code outside of variable, method, class, package and import declarations need to be contained inside of a method
Fixed syntax on your if statement, removed rogue semi colon
if ((d % 2) && (d% 3)); you have a semicolon ; at the end,
remove it.
If d == 18, then ((d%2) && (d%3)) = (0 && 0) = 0 So in this
case, What java sees is: if(0){ // ... }
If I remember correctly, this is valid in C/C++, but not in Java. That is why you get error.
Anyways, to fix the problem, you can do this:
if (((d % 2) == 0) && ((d % 3) == 0)){
System.out.println("Divisible!");
} else {
System.out.println("Not divisible!");
}
if condition expects boolean. Mod operation would not return boolean, this is why compiler is intelligent and gives you this error.
if you try to run
if (1 && 2) // this will give you an error as well.
The expressions need to evaluate to a boolean (either true or false) in order to understand operators like && and ||
Moreover, you statement will not work since you are using ; at the end.

Java post increment and pre increment

The following code in Java:
int a = 0, b = 0, c = 0;
boolean d = (a++ > 0 && b-- < 0) || --c < 0;
results in the values:
a = 1, b = 0, c = -1 and d = true
I don't understand why a is = 1, because it is a post-increment and should also react the same way that value b does. Also, if I change the b-- to --b it still has no effect on the value of b.
What is the best way of understanding this logic?
a++ > 0 returns false, since a++ return the previous value of a (0).
Therefore b-- < 0 is not evaluated at all, since && is a short circuiting operator. The right operand is only evaluated if the left operand is true.
--c < 0 is evaluated, since the first operand of the || operator is false, so the second operand must be evaluated.
After d is evaluated, the value of a is 1, since a was incremented. b remains 0, since b-- wasn't executed. c is -1 since --c was executed.
And d is true since --c < 0 is true.
After the expression runs then a will indeed be 1 as the post increment operator has then executed.
During the evaluation of the expression a is 0 as far as the expression is concerned (but a is now 1 for other code), so the first part of the logical OR, your logical AND, is evaluated as false and the b post decrement does not get evaluated.
The second part of the logical or then runs, and the pre-decrement executes to reduce c to -1, which then causes the comparison to evaluate to true, hence d being true.
Expand the different clauses to separate variables and run through a debugger for a more interactive explanation of what's happening.
a++ at moment of comparing is NOT >0, so b part is not evaluated, and not incremented.
Second part of && and || expressions is not evaluated if cannot change result. For && first false determines result false.
Analogically, first true determines result of || (but not here)
a++ effectively means a= a+1
So, the existing value of a (=0) is used for evaluating the expression, and later on the value of a is incremented. So, a becomes 1.
Regarding why b =0 and why --b has the same effect as b--, the value of b is unchanged because of &&. Since a++ > 0 is not satisfied, the next expression b-- < 0 is not evaluated and value of b remains 0. && stops evaluation once the expression evaluates to false, while || stops evaluation once the statement evaluates to false.
When you write a++ OR b--, it passes the value 'a' and 'b' currently holds, and then modifies the variables.
So your expression is simply,
boolean d = (0 > 0 && 0 < 0) || -1 < 0;
Now while evaluating, (0 > 0 && 0 < 0) -> first expression returns false and you have used short-circuit AND operator. Meaning don't evaluate the right hand side if it isn't necessary. As LHS of && returns false, b-- won't be evaluated.
And we have 'd' is true.
Remember,
Post-increment within expressions --> assign current value first, modify later.
Pre-increment within expressions --> modify first, assign updated value later.
Refer this link for better understanding short circuit operators:
Short-Circuit Explanation
Please Execute This code..
int a = 0, b = 0, c = 0;
System.out.println("b = " + --b);
b=0;
System.out.println("b = " + b--);
System.out.println("a = " + a++);
a=0;
System.out.println("a = " + ++a);
System.out.println("c = " + c--);
c=0;
System.out.println("c = " + --c);
a=b=c=0;
boolean d = (a++ > 0 && --b < 0) || --c < 0;
System.out.println("d = " + d);
I think you understand full logic.

Greatest common divisor

I try to find the greatest common divisor for two integers. But I don't understand what is wrong with my code:
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int a = s.nextInt();
int b = s.nextInt();
while (a != 0 | b != 0) {
if (a >= b) {
a = a % b;
} else {
b = b % a;
}
}
if (a == 0) {
System.out.println(b);
} else {
System.out.println(a);
}
}
}
Just change
a != 0 | b != 0
to
a != 0 && b != 0
Because you version will be work even a or b equals 0.
But you need to exit from loop when one of them equals 0.
&& - better than & because in your case you don't need to check
right-hand operator if left equals 0
It is easier to calculate the GCD if we understand the core logic. Try to understand what we need to do, and how we are going to do it before implementing the program.
What we are trying to find is the greatest number that divides both a and b.
So the question arises that how we are going to do it. We do a loop just like you did, but for this case, let's initially assume that a is greater than b.
The first step is to start the loop, while the calculation is not finished. The condition in our case is, we have to stop when any one of the two numbers becomes zero.
while (a != 0 && b != 0)
{
// Do the calculation here.
}
Now we have to write the calculation. We have assumed that a is greater than b or both are equal.
We keep on assigning the remainder of a divided by b to a.
while (a != 0 && b != 0)
{
a = a % b;
}
This makes the solution only half correct, we will have to deal with the other case, that is when b is greater than a. Why this happens is after some set of iterations, a will become less than b, and that will result in a being set to 0.
So let's do the same solution to the other case, when a is less than b.
while (a != 0 && b != 0)
{
if (a > b)
a = a % b;
else
b = b % a;
}
And this is what you wanted to achieve. The non-zero value will be the solution.
Let's just not stop here, and see why your current version does not work. You have had this in your condition.
Your condition is:
a != 0 | b != 0
Here, you are using bit-wise operator OR, between two boolean values, which comes to the following. Assume any of a and b is zero.
Case 1:
a != 0 => true
b != 0 => false
true | false => true
Case 2:
a != 0 => false
b != 0 => true
false | true => true
Therefore as you see in the above cases, it continues to loop until both becomes zero, and hence you will always be reported as the GCD is zero.
Hope this helps.
You probably need to implement the Eudidean's Algorithm (which is actually about the math) But here is an example of how does this alg works
private static int GCD(int a, int b)
{
int remainder = a % b;
while (remainder!= 0)
{
a = b;
b = remainder;
remainder = a % b;
}
return b;
}

Statement evaluation on if statement java

If the below "if" stmt evalutes to TRUE then the value of Output = 20 or else 10..
Can someone explain how the increment operator works here.?
public class Test {
public static void main(String[] args) throws IOException {
int Output = 10;
boolean b1 = true;
if ((b1 == true ) && ((Output += 10) == 20)){
System.out.println("We are Equal = " + Output);
}
else{
System.out.println("Not Equal = " + Output);
}
}
}
It's not so much the += operator that is working differently; it's the && operator.
The && operator short circuits. If b1 is false, there's no way that b1 && (anything else) can be true, so it stops evaluating. As such, Output += 10 is not evaluated if b1 is not true, so Output will be 10.
If b1 is true, then it must continue to see if the remainder of the condition is true. In doing so, it must evaluate Output += 10, thereby increasing the value of Output by 10, making the value of Output 20.
The integer value 10 is added to the current value of Output. After this, the value of output is compared using the == operator, which only operates on booleans.
In this particular piece of code, since b1 is true and and Output is 20 after its value is increased by 10, the condition of the if block is true, therefore the else will be discarded and whatever code is inside the if block will be executed.
1) +=
means a "Pre-increment". So, with Output=10 the if block would proceed as below
if ((b1 == true ) && ((Output = Output + 10) == 20)){
here, value of Output will be compared with 20 once incrementation is done..So, during the first time
execution of the if block.. it would proceed as below..
if ((b1 == true ) && ((20) == 20)){
2)=+
means a "post-increment". So, value of Output will be compared with 20 before incrementation..So, during the first time execution of the if block.. it would proceed as below..
if ((b1 == true ) && ((10) == 20)){
hope this explaination helps :-)

Syntax Question IF ELSE (Java)

what is the java syntax for saying
if x is not equal to a or b
I am trying to write an if else statement .. if a certain value is not equal to say 2 or 3 then do something else do something else :) thats confusing lol
Try this:
if (x != a && x != b) {
// Something (action x)
} else {
// Something else (action y)
}
Note that it's an "and" condition even though you're asking whether x is equal to a or b because each condition is negative. The other way you could represent this (if you find it more readable) is:
if (!(x == a || x == b)) {
// Something (action x)
} else {
// Something else (action y)
}
And at that point you may find it more readable still to get rid of the negation, but switch round what you do in the blocks:
if (x == a || x == b) {
// Action y
} else {
// Action x
}
These three blocks of code all do the same thing, but I think I'd find the bottom one the most readable as the condition is simple.
if ((x != a) && (x != b)) {
// do stuff
} else {
// do other stuff
}
if( x != a && x != b )
Notice it's an &&, not an ||
The condition ( x != 2 || x != 3 ) is always true: if x = 2, then x != 3 and the condition is true. if x = 1, then x != 2 and the condition is true.
What you're really saying is: if x is not one of 2 or 3, which is, x is not in the array [2,3], which is "x is not 2 neither 3", which is x != 2 and x != 3.
directly mimics the english sentence: if x is not equal to a or b
if (!(x == a || x == b))
{
doSomething();
}
else
{
somethingElse();
}
but if the extra not operator and parentheses hurts your eyes, use this(note the absence of the word Or in this condition, not anymore parallel with english sentence):
if (x != a && x != b)
{
doSomething();
}
else
{
somethingElse();
}
see my answer on programmer's ignorance pet peeve and Is it acceptable to only use the ‘else’ portion of an ‘if-else’ statement?, why i advocate constructing simple conditions(directly mimics english sentence, i.e. without sticky ANDs and too much NOTs)
if(x!=a && x!=b){
//do...
}
in java if-else is a control statement which is used to test condition and transfer the control based on the evolution of condition.
if((x!='a')||(x!='b'))//if a,b is char use quotes else avoid
{
//if expression is true
}
else
{
//if expression is false
}
if you want that code should be executed when x=a and x=b both then use '&&' instead of '||'.
For more details:
http://java.meritcampus.com/t/60/If-else-if-ladder?tc=mm70

Categories

Resources