b = 5;
loopiterations = 0;
while (b-- > 0) { // Use a postfix decrement
loopiterations++;
}
System.out.println("Postfix decrement operator used, loopiterations = " +
loopiterations + ", b = " + b);
The result is
Postfix decrement operator used, loopiterations = 5, b = -1
I don't understand why the value of b is -1. The value of b starts from 5 (after while loop it's value is 4) and then ends at 1 ( after the while loop it is 0) and then the iteration from 5 to 1 is 5.If how I think is right, why is the value of b is -1 after looping. Thank you.
This block of code
while (b-- > 0) {
// do something
}
is semantically the same as
while (b > 0) {
b--;
// do something
}
b--;
The loop while (b-- > 0) exits as soon as b == 0, but because of the post decrement operation b will be one last time decrement and hence b will have the value of -1 when printing.
**postfix increment or decrement actually happens after using value**, the initial value of b is 5 so in the first iteration 5 is checked for condition after the last iteration, b becomes 0 after its value (1 at time of comparison) has been decremented, then 0 is checked but the condition is false but due to postfix decrement it's value becomes -1.
postfix -> first use value then decrement or increment that's how it works
This is because when b == 0, the postfix will return false and your while loop will terminate. However, the postifx will still subtract one from b. Therefore, the loop is executed 5 times, and iterations = 5. However, b is decremented 6 times.
Related
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.
I have been doing Java for a decently long time and I stumbled across this piece of code. I don't understand how it works:
int func(int num){
int counter=0;
for(int i=5;num/i>=1;i=i*5)
counter=counter+num/i;
return counter;
}
This function is a part of the program which counts the number of trailing zeros in a factorial. What I don't understand is the for loop part. The limit is usually the second condition and out here it is "num/i>=1".
I don't understand that if i take num as 100, the limit would be 100/5 = 20? But the part ">=1" is confusing me.
In the java for loop, there is no limit. You might be thinking of BASIC.
In the java for loop, the 2nd expression is the termination expression. The loop will keep looping for as long as the termination expression is true.
(That's why I prefer to think of it as the continuation expression, but never mind me.) Ofcourse, this expression must evaluate to a boolean.
100/5 would be illegal as a termination expression, because it is of type int, not type boolean.
100/5 >= 1 is a legal termination expression. The loop will repeat for as long as num/i is larger than or equal to 1.
More information about the java for loop:
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html
Your loop is equivalent (more or less) to this:
int func(int num){
int counter=0;
for(int i=5; i<=num;i=i*5)
counter=counter+num/i;
return counter;
}
for a case where num = 100
the first iteration will be i=5 and num=100
the second iteration will be i=25 and num=100
the third iteration will be i=125 and num=100 in this case the loop exists because the condition (num/i >= 1 [which is equivalent to] i<=num) is no longer fulfilled (Edit: just in case num/i = 0 in this case)
This condition instructs the loop to continue until num/i becomes one or less. This is simply a boolean condition, which may be true or false. Once the condition becomes false, the loop stops.
Since i becomes five times greater than it has been during the prior iteration, the loop effectively divides by five to the power of k+1, where k is the number of iterations.
You can rewrite this by multiplying both sides by i:
for (int i=5 ; num >= i ; i=i*5) {
counter += num/i;
}
num/i>=1 is, in fact, a condition.
Let's look at a few examples
num = 100; i = 5;
num/i >= 1; // true because 100/5 is greater than 1
num = 100; i = 200;
num/i >= 1; // false because 100/200 is not greater than 1.
As you can see, num/i >= 20 is a condition that evaluates to true or false. The only tricky thing is that there is an expression (num/i) in the condition, rather than a single number.
num/i>=1 means your loop will be executed as long as this statement is true, so as long as the result of num divided by i ist greater
The thing is, that i is your loop variable, so it will grow everytime your loop is execute. So num/i will get smaller, until it is eventually smaller than 1.
Example: Num = 50
Loop: 50/5 >= 1? --> True
Loop: 50/25 >= 1? --> True
Loop: 50/ >= 1?25 --> False
At this point your Loop will stop.
Ok let's take a simple example.
Here is the code:
public class Fact {
public static void main(String[] args) {
new Fact().func(98);
}
int func(int num) {
int counter = 0;
for (int i = 5; num / i >= 1; i = i * 5) {
System.out.println("num: "+num + "/" + i + " = " + num / i);
counter = counter + num / i;
System.out.println("Counter = " + counter);
}
return counter;
}
}
And here is the output for the example of 98.
run:
num: 98/5 = 19
Counter = 19
num: 98/25 = 3
Counter = 22
BUILD SUCCESSFUL (total time: 0 seconds)
What happens is that: num/i is evaluated for the first loop step to 98/5 = 19.6 but it is rounded by java to 19 (it is integer).
num/i>=1 is a condition. How did you conclude 20 (100/5=20) will limit for the loop. denominator i is updated by the factor of i in each loop and check the condition. So for input num = 100 this how the loop will process
First
for(i=5; 100/5>=1; i=25) condition is true
Second
for(i=25; 100/25>=1; i=125) condition is true
In third iteration condition fails since 100/125 is not >=1.
100 has 2 zero and loop iterated 2 times.
I was taking a java course on edx. For this question, the condition is x++==4. I tried and found out that only when i enter an x value of 4, the condition evaluates to true. But why?
1) Why is it that when i enter x = 3 or x = 2 the condition evaluates to false?
2) Why is x++==4 even a condition? it's like x = x + 4. How can it ever be true or false? It is an equation, not like x > 3 etc.
if (x++==4) { ... }
could simply be replace by the following lines
boolean b = (x == 4);
x = x + 1;
if (b) { ... }
You evaluate if x is equals to 4 and then increment it using the Postfix increment Operator ++
Why is it that when i enter x = 3 or x = 2 the condition evaluates to
false?
Because
3 == 4; // false
2 == 4; // false
It is because x==4 IS a condition? therfore x++ is just an increment on the value if the variable
Dont let the ++ to trick your mind...
the same can happen even on ugliest ways like
if (x---5==0) { which just happens to be
if ((x--)-5==0) {
int i = 0;
boolean b = true;
System.out.println(b && !(i++ > 0))
When I compile the above code I get a value true back.
But how can that be, since the second part of the argument (since b is true already) basically translates to
(0 + 1 > 0) => (1 > 0)
which should return true. Then the statement would be true && false, which is false.
What am I missing?
Java behaving correctly :)
i++
That is postfix increment.
It generated result and then incremented that value later.
!(i++ > 0) // now value is still zero
i++ will use the previous value of i and then it will increment it.
When you use ++ ,it's like
temp=i;
i += 1;
i=temp; // here old value of i.
language specification on Postfix Increment Operator ++
the value 1 is added to the value of the variable and the sum is stored back into the variable. ......
The value of the postfix increment expression is the value of the variable before the new value is stored.
Possible solution would be ++i, which is as per your requirment,
Prefix Increment Operator ++
The value of the prefix increment expression is the value of the variable after the new value is stored.
You want to use ++i if you want to increment i and return the incremented value. i++ returns the non incremented value.
b && !(i++ > 0)
i++ is post increment so value of i here is still 0
0>0 false
b && 1 is true(since !(0) is 1)
So you are getting true.
i++
the increment happens after the line is executed
so you better keep
++i
You can see how ++ operator works on following example:
public static void main(String[] argv) {
int zero = 0;
System.out.println(zero++);
zero = 0;
System.out.println(++zero);
}
Result is:
0
1
Take a look at the following code:
class experiment{
public static void main(String[] args) {
int k = 3;
while (k-- > 0) {
System.out.println(k + "\n");
}
}
}
Expected output:
2
1
Actual output:
2
1
0
Postfix operators have higher precedence than operational operators. Hence k-- should be evaluated first before the k > 0, but looking at the output, k > 0 gets evaluated first. Do I miss something simple here?
Precedence has nothing to do with it. The value of 'k--' is 'k'. There is a side-effect of post-decrementing 'k' but it doesn't affect the operand value.
Yeah you are right. k-- will be evaluated first. But it is really evaluated to k. And after the current operation involving it is completed, it's value is increased. So, first the current value is used and then the increment happen.
Had you used --k, you would have got the expected output.
Just try these examples, you will understand: -
int k = 4;
System.out.println(k-- + " : " + k); // prints 4 : 3
int x = 5;
System.out.println(--x + " : " + x); // prints 4 : 4
You're right, the k-- is evaluated before the > 0. However, the result of that evaluation is k, not k - 1, as the -- is post-fix, not pre-fix.
So, the first time the > is evaluated, it is effectively 3 > 0, because although k now is 2, the result of the expression k-- is 3. By the time the print comes around though, k = 2, hence 2 is output first. This is why you get one more iteration than (I guess) you were expecting.