prefix and postfix increments while comparing variables - java

could someone explain why this code output is
not equals
not equals 2
in the first if statement it seems that a = 0 b/c is a postfix increment; therefore a will not increase untile next line; however, the two a's are not equal why? and in the second if when I run the debugger the value of a is 2, but the test is false, why?
public static void main (String[] args)
{
int a = 0;
if (a++ == a++) {
System.out.println("equals");
} else {
System.out.println("not equals");
}
if (++a == 2) {
System.out.println("equals 2");
} else {
System.out.println("not equals 2");
}
}

it's not that it waits until the next line. The == is a 'logical' operator so the expression on each side is evaluated first, each of which has the side-effect of incrementing the 'a' value. The result of the 1st increment is used on LHS, result of 2nd on RHS.
In these cases it matters not whether the operator is 'prefix' or 'postfix'

a++(post increment) would increment a first and then assign it to the variable. in your first case
(a++==a++) in the first post increment a value would be incremented by 1 first but not assigned yet, but when it reaches the second a++, now the a value is assigned and you are incrementing it again.
for example
if say a=0;
(a++==a++) would be (0==1)
so now the a value would be 2 after evaluating the if.
for your second case
(++a==2) here a would be incremented to 3 , (3==2) which is false thus the else if executed

EDIT: just realized you asked also for first not equals, this just answers the second one yet.
Because
a is already 2 (already incremented twice)
++a is 3 so
3 == 2 is false since prefix is applied before evaluation.

Related

Boolean logical operators for flow controls in java

Can't we use Boolean logical operators (such as &,|,!,^ etc) in java flow controls ( for loop,while loop etc) ???
I want to print all even numbers between 1 and 100.So I used below two source codes.
import java.util.*;
class Example{
public static void main(String args[]){
int i=1;
while(i<100){
if(i%2==0)
System.out.print(i+" ");
i++;
}
}
}
This code is compiled and prints all even numbers between 1 and 100.
import java.util.*;
class Example{
public static void main(String args[]){
int i=1;
while(i<100 & i%2==0){
System.out.print(i+" ");
i++;
}
}
}
This code is compiled without any error.but doesn't give any print.
Why is that ?
Can't we use Boolean logical operators within a while loop ?
Remember that the while loop condition is the condition to continue the loop, which means that when the condition is false, the loop stops.
If you negate the condition in the second code:
!(i<100 & i%2==0)
Using De Morgan's Law, This is equivalent to:
i>=100 | i%2!=0
Or in words:
i is greater than or equal to 100 OR i is odd.
This is the stopping condition of the while loop. Well, i is initially 1, which is odd, so the loop stops without even executing one iteration.
In other words, you can't rewrite the first code as the second code. They are not equivalent. What goes in the if condition goes in the if condition. You can't "merge" it into the while condition, because they are for different purposes.
I also recommend && for the logical AND, as it only evaluates the right operand when necessary. For more info, see What is the difference between & and && in Java?
The error is in this line:
while(i<100 & i%2==0){
& should be replaced with &&:
while(i<100 && i%2==0){
U have tearn the logical operators...
and it is a logical operator it can be true only if 2 operators are true( x>5 and y<7) will be true if only x>5 is true and y<7 is true that is give us the condition is true but if one of them is not verified the condition is false....
but if we have or operator the condition will be true only if one of them is true or both........
so let's explain ur code.
You have condition (i<100 and i%2==0).
0%2 ==0 so it is true and of course i<100 so while returns true(both true at the same time) but when i==1 here we have a problem 1%2!=0 so i<100 is true but i%2==0 is false so we get **true && false ** the result is false .
(true && true==true) (false && true==false) (false and false==false) (true ||true==true) (true || false==true) (false||false==false)

I don't really understand the do { } while structure

I'm trying to learn Java, I studied Pascal in high school and it has the repeat until..; instruction.
I want to solve an exercise where I'm supposed to keep entering numbers until the penultimate + antepenultimate numbers equal the last number I entered.(a[i-2]+a[i-1] = a[i]); I'm doing it without arrays but that doesn't really matter.
In Pascal it would be easy because repeat until is more easier to use
For ex it would be
repeat
...
until ((a[i-2]+a[i-1] = a[i]) and (n=3));
n is the number of values I entered
I can't figure out how to introduce it in Java, so far I did this but it doesn't work if I enter 2 2 4. It should stop but it keeps asking for numbers
int pen = 0, ant = 0, s = 0, n = 1;
int ult = input.nextInt();
s = s + ult;
do {
do {
ant = pen;
pen = ult;
ult = input.nextInt();
n++;
s = s + ult;
} while (ant + pen != ult);
System.out.println(n);
} while ((n == 3) || (n < 4));
ult is the last number I enter, s is the sum of the numbers entered.
Could anyone tell me how to set the conditions so it will stop if I enter the values 2 2 4?
A Do-While loop runs the code in the loop first. It evaluates the logic last, and then if it's true it repeats the code inside the loop, and so on until the logic is false.
The way to solve tricky problems like this is to get out a sheet of paper and record what each variable does. Step through each line like a debugger and record what's being stored in each variable as the program progresses.
It's the best way to do it. You'll find that you'll gain a deeper understanding of how your programs are working.
Java isn't any more magic than Pascal, the issue might be you've had a long break from programming :). Anyway, its been a while since I wrote anything in Java, but the issue I could spot in your code is just that n equals three after you've entered three ints, and so the outer loop continues.
int pen = 0, ant = 0, ult = 0, n = 0;
do {
ant = pen;
pen = ult;
ult = input.nextInt();
} while (++n < 3 || ant + pen != ult );
assert n >= 3;
assert ant + pen == ult;
Note that ever since Pascal everything has been zero indexed instead of one indexed.
Pascal uses the form:
repeat
doStuff();
until (boleanValue);
Java is basically the same, except for one important point:
do
doStuff();
while (~boleanValue);
The important difference is that "~" before booleanValue. The Pascal repeat ... until keeps running until the boolean evaluates to true. In Java the do ... while keeps running until the boolean evaluates to false. When converting from Pascal to Java you need to switch the boolean to work the other way.
The primary difference between while loop and a do-while loop is that while loop does eager condition check where as do-while loop does lazy condition check
while: Expression is evaluated at the top of the loop
syntax:
while (expression) {
statement(s)
}
(taken from http://www.w3resource.com/c-programming/c-while-loop.php)
Example:
public class WhileDemo{
public static void main(String args[]) {
boolean isSunday = false;
while(isSunday) {
System.out.println("Yayy.. Its Sunday!!");
}
}
}
Output: (nothing is printed on console)
Reason: Since isSunday is false, the body of loop is not executed
do-while: Expression is evaluated at the bottom of the loop. Therefore, the statements within the do block are always executed at least once.
syntax:
do {
statement(s)
} while (expression);
(taken from http://www.w3resource.com/c-programming/c-do-while-loop.php)
Example:
public class DoWhileDemo{
public static void main(String args[]) {
boolean isSunday = false;
do {
System.out.println("Yayy.. Its Sunday!!");
} while(isSunday);
}
}
Output: Yayy.. Its Sunday!!
Reason: The body of do is executed first, there by printing Yayy.. Its Sunday!! and then the condition while(isSunday); evaluates to false since isSunday is false and the loop terminates
You're only missing one thing from your problem. Your explanation of the Pascal code is almost correct, but wouldn't work without some modification.
In Java, use short-circuit logical operators to do the check.
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html
Not tested:
int n = 0;
int a[] = new a[3];
do {
n++;
a[0] = a[1];
a[1] = a[2];
a[2] = input.nextInt();
} while ((n < 3) || (a[0]+a[1] != a[2]));
System.out.println(a[2]);

What causes this recursive function to crash compared to another nearly identical one? [duplicate]

This question already has answers here:
How do the post increment (i++) and pre increment (++i) operators work in Java?
(14 answers)
Closed 7 years ago.
This causes a Stack Overflow error. I just need help explaining why this one crashes compared to the correct one which is similar. I have used the debugger, but it is still unclear to me.
public static void main(String[] args) {
countForwards(5);
}
public static void countForwards( int num ) {
if (num >= 0){
countForwards(num--);
}
System.out.print(num + " ");
}
I know this is the solution but I don't understand why it is different
public static void countForwards( int num ) {
if (num >= 0){
countForwards(num - 1);
}
System.out.print(num + " ");
}
countForwards(num--) passes the original value of num to the recursive call, which means the recursion never ends.
countForwards(--num) would allow the recursion to end.
After seeing all the traffic this question got, I thought it would be worth it to expand the answer a little.
As paxdiablo commented, even though countForwards(--num) allows the recursion to terminate, it behaves differently than countForwards(num-1).
Both variants would cause the following series of recursive calls :
countForwards(5)
countForwards(4)
countForwards(3)
countForwards(2)
countForwards(1)
countForwards(0)
countForwards(-1)
but they will output a different series of numbers when the recursion unwinds :
num - 1
-- num
-1
-1
0
-1
1
0
2
1
3
2
4
3
5
4
The reason for the difference is that num-1 doesn't change the value of num while --num decrements num.
num-- uses a postfix operator -- which means that original value i.e. num is passed and its value is decremented after it is passed.
The interesting thing about a postfix operator i.e. the one we are using in this example is that operation is performed and then the value is incremented or decremented. Please refer to official documentation about operators in java
class PrePostDemo {
public static void main(String[] args){
int i = 3;
i++;
// prints 4
System.out.println(i);
++i;
// prints 5
System.out.println(i);
// prints 6
System.out.println(++i);
// prints 6
System.out.println(i++);
// prints 7
System.out.println(i);
}
}
Post-Decrement
Post-Decrement takes the form variable-name operator. This tells the compiler to first use the original value and afterawrds decrement it, so if we have something like this:
for (int i = 10; i > 0; i--)
{
System.out.println(i);
}
The output will be as follows
1: 10
2: 9
3: 8
4: 7
5: 6
6: 5
7: 4
8: 3
9: 2
10: 1
Pre-Decrement
Pre-Decrement takes the form operator variable-name and is used when you want to decrement before you use the value. The same code above would terminate at 0 instead of 1. This is because the function decremented the value before it used the value.
How does this apply to recursive calls?
Each recursive call is it's own stack, so when you pass num-- to the recursive function, you're literally passing the original value of num, and when the child call terminates (in this case never) the parent call will then decrement num. Since you don't have another base case which correctly terminates the call, it results in infinite recursion.
Actually it is happening due to post decrement operator in the method.
public static void countForwards( int num ) {
if (num >= 0){
countForwards(num--);
}
System.out.print(num + " ");
}
Now when the function is calling the countForwards again it is always taking value of num as 5 due to post decrement in the method, please try to change as pre-decrement
public static void countForwards( int num ) {
if (num >= 0){
countForwards(--num);
}
System.out.print(num + " ");
}
This will be work because value is first decremented and then that value is using method.
as function is calling again and these are primitive and stores in the stack. Thats why it is showing stack overflow.
public static void countForwards( int num ) {
if (num >= 0){
countForwards(num - 1);
}
System.out.print(num + " ");
}
This is working because this is an expression which try to solve first itself and then the function can use the value of that expression. I hope it will answer your question.

While and do while loops

I'm new to this site and also very new to Java and I'm trying to understand the do while loops
Question: What is the output and why?
public class DoWhile {
public static void main(String[] args) {
int i = 1;
do {
System.out.println("i is : " + i);
i++;
} while(i < 1);
}
}
I get that the output is "i is : 1" but I'm trying to understand why. It stops once it hits while because i isn't less that 1, right?
Just trying to get my head around it so any help will be appreciated.
Yes. Correct.
do { } while (condition);
This will perform the code at least once, regardless of the condition. After the first execution it will check the condition, which will evaluate to false (1 is not smaller than 1) and thus it will stop.
Yes, the output is 1 because in a do-while loop the statements within the do block are always executed at least once.
After the do block is executed the i value becomes 2 and the while block is not executed.
The difference between do-while and while is that do-while evaluates its expression at the bottom of the loop instead of the top. Therefore, the statements within the do block are always executed at least once
Yes, the output is
i is : 1
The do-while loop will always execute at least once, because the condition isn't evaluated before the loop is entered; it's only evaluated at the end of each iteration. This is in contrast to the while loop, whose condition is checked before the first iteration as well as after each iteration.
i is 1 at the start, then print occurs, then i is incremented to 2. Then the condition is evaluated -- it's false, so the loop terminates.
The output is just 1 becuase the do causes the loop to execute at least once, but the condition in the while doesn't aloow the loop to reiterate, because i is never less than 1
It is no more 1
public class DoWhile {
public static void main(String[] args) {
int i = 1; // i is 1
do {
System.out.println("i is : " + i); //still i is 1
i++; // this makes i = 2;
} while(i < 1);
}
}
if you notice the comments it is no more 1 after the first iteration

increment a number in java until it gets to 100 than decrement down to 0 continously

I'm making a game where there is a goalie. i want him to move back and forth forever. i have an int called goalieposx (goalie position on the x axis) and i want this is go up by 1 until it hits 200, then go down by one till its back a 0 and repeat. I've tried the folllowing
//this bit isnt in the method, its outside as global varibale
boolean forward=true
//this bit is in a method which is continiouly called nonstop
if (goalieposx<200){
forward=true;
}
else if (goalieposx>200){
forward=false;
}
System.out.println(forward);
if(forward=true){
goalieposx++;
System.out.println("forward");
}
else if (forward=false){
goalieposx--;
System.out.println("backwards");
}
}
this method is called continously. It prints true until it gets to 200, then it prints false. However, it always prints forward, never backward. So conclusion is: the boolean changes as expected but the first if is always called, it seems to ignore the condition
ive also tried this
if(forward = true){
if(goalieposx==200){
forward=false;
}
else{
goalieposx++;}
}
else{
if(goalieposx==0){
forward=true;
}
else{
goalieposx--;}
System.out.println(goalieposx);
}
but this doesnt work either, it prints 1 then 2 etc upto 200 then prints 200 forever. Anyone know how i can solve this? is an if statement the wrong idea altogether?
This is why you should never do comparison for boolean types in if, while, for, whatever. You have just done the assignment in your if statement:
if(forward=true)
the above if statement will always evaluate to true. The problem with this is, this compiles successfully in Java, as syntax wise it's alright. Compiler just checks the type of expression in if evaluates to boolean or not. And it does, so it's ok with it.
You need to do the comparison:
if(forward==true)
.. but as I said, you should not do comparison for boolean types. So, simply doing this:
if(forward)
would be enough.
You also don't need those else if in both the conditions. Just an else will work fine. Well, I don't understand the use of boolean variable at all. It seems like you don't need it. You can change your code to:
if (goalieposx<200){
// forward=true;
goalieposx++;
System.out.println("forward");
}
else {
// forward=false;
goalieposx--;
System.out.println("backwards");
}
What you were previously doing is, setting a boolean variable, based on a condition, and using that boolean variable as condition to execute another if-else block. Well, whatever you are executing in the 2nd if-else block, can simply be moved in the original if-else block, without taking the help of the middle-actor boolean variable.
if(forward=true) does not do what you thing it does.
In java = is the assignment operator and == is the comparison operator. What you are doing with that statement is saying "if assign forward to true" which will set forward to true and always return true.
What you mean to say is if(forward) and if(!forward).
In fact you don't need the else if just an else as if the boolean is not true it must be false.
A better way to do it is to get it to move to the left by adding a minus number, and to the right by adding a positive number. Here's an example of doing this with a loop:
for(int i = -10; i < 100; i++) {
xPosition += i;
}
This would add -10 then -9 etc. to the position.
In your if statements, you need to put two equal signs to check for equality.
if (forward == true){
// execute code
}
EDIT 1:
if (forward)
would be much simpler.
First let's examine what you have already written:
if (goalieposx<200){
forward=true;
}
else if (goalieposx>200){
forward=false;
}
The problem with this code being first is that it while it might set the direction to false once 'goalieposx' has reached 201, in the next call, it will set the direction back to true.
Instead, try using this clever alternative:
//This goes before the infinite loop method
counter = 0;
//Then in the infinite loop method
counter++;
if(counter > 100) {
counter = -100;
}
goalieposx = 100 + counter; //(this shifts counter from
// between -100 and 100 to 0 and 200)
The problem is you are setting the direction based on the value of the integer, instead of whether a condition has previously been met. Try this:
//this bit is in a method which is continiouly called nonstop
if (forward && (goalieposx>200)){
forward=false;
}
System.out.println(forward);
if(forward=true){
goalieposx++;
System.out.println("forward");
}
else if (forward=false){
goalieposx--;
System.out.println("backwards");
}
}

Categories

Resources