I'm coding a simple shoot-a-cannon-ball 'game' for my class and I have to have the program print "HIT" when it hits the target. The code I am using is (h being the y axis and d being the x axis):
if (h > 100 && 680<d<780)
{
write_string("HIT");
}
However it will print "HIT" even if just one of these conditions is satisfied. How do I make it so BOTH of these conditions have to be satisfied before it will perform the operation?
If I need to post more code for context I can.
The expression 680<d<780 doesn't do what you think it does.
It first checks if 680<d, which then gets evaluated to true or false.
This resulting expression is then compared to see if it is less than 780, meaning that you could get the condition true < 780 or false < 780 (Both of which are true, since true == 1 and false == 0).
You probably meant 680<d && d<780, which checks if d is in the range from 680 to 780 through a boolean AND condition.
if (h > 100 && 680 < d && d < 780) {
write_string("HIT");
}
You can only do one less than comparison at a time. Do them separately and check are they both true using '&&' operator.
That is because < is a binary operator, and as a result, your expression gets evaluated in ways that you didn't want.
Checking the operator precedence tables, it seems your expression is getting evaluated as (h > 100 && (680 < d) < 780), in which case it is true independent of the value of d (because (680 < d) = true will result in 1 < 780 and (680 < d) = false will result in 0 < 780). But the value of h should affect still.
Anyway, you have to rewrite your if condition as (h > 100 && 680 < d && d < 780).
Related
Any idea why the else if statment will be never executed ? The value of difference is constantly changing when the program runs.
double difference = abs(reale_x[0] - reale_x[1]);
if (0 <= difference < 45) {
timer_counter += 1;
if (timer_counter == 30) {
cout << "CLICK" << '\n';
}
}
else if (difference > 50) {
timer_counter = 0;
}
That is not how comparation works in c++.
What this code
if (0 <= difference < 45) {
does is it first compares if 0 is smaller or equal to difference. It is then "replaced" by a bool value either true or false. And then a bool value (so either 1 or 0) is compared to 45. And it will always be smaller than 45. What you have there is an always true statement.
So the way you would write this if statement is
if (difference >= 0 && difference < 45){
Note that because of your else if statement it will not execute if the difference is >44 and <51
if (0 <= difference < 45) will be executed as if ((0 <= difference) < 45), which will be either 0<45 or 1<45 and will always be true. That's why the else part is not getting executed.
in mathematics, we see and write 0 <= x < 45 or something like that to define the range of the variable x. But in order to tell the computer the same thing, you have to tell more clearly. Saying, to have to tell the compiler, that the value of x is greater than or equal to zero and at the same time, that value will be less than 45, and you can tell the compiler by this statement: difference >= && difference < 45 . the && is an 'AND' operator in most of the languages.
if ((pCommandPts>=tempChar.commandValue) && ((pCommandPts - tempChar.commandValue)<=0))
If pCommandPts is an int with the value 6 and tempChar.commandValue is an int with the value 3, why would this statement evaluate to false?
Left part of this expression is true in case of 6 and 3, but 6-3 is not lower or equal to zero
&& ((pCommandPts - tempChar.commandValue)<=0))
That code makes no sense, and it's almost certainly a bug.
If you rearrange the inequalities, you get:
a >= b && a <= b
Which is only true if a == b, which is not true for your case 6 != 3
1.Imagine condition if (obj.is_x() || obj.is_y() || obj.is_z())
Will obj.is_y() and obj.is_z() be called and evaluated if obj.is_x() returned true ?
2.Is this a bad idea(in general)? Does this code look bad ?
bool isbn13_prefix_valid (const string& prefix)
{
unsigned num = stoi(prefix);
if (num == 978 || num == 979) return 1; //super common ones
else if ( num >= 0 && num <= 5 || num == 7 || num >= 600 && num <= 649
|| num >= 80 && num <= 94 || num >= 950 && num <= 989
|| num >= 9900 && num <= 9989 || num >= 99900 && num <= 99999)
return 1;
return 0;
}
No, it will not, due to short-circuiting.
Yes, that code looks bad. Not because it's incorrect, but because you're stuffing an extremely long conditional into a single if statement. Try refactoring your code to make it cleaner.
Your code is absolutely fine. I'd like to see a comment where these strange numbers come from, that's all.
Turning it into a dozen trivial functions as has been suggested is in no way helpful. It actually makes it a lot harder to read the code, because it gets spread out over many many lines of code. Yes, it is complex. But that's due to the problem being complex, and trying to spread the complexity out doesn't help one bit.
Your actual question: In a || b, a is evaluated first. If it is true, then b is not evaluated and the result is true. If a is false, then b is also evaluated and the result is true or false, depending on the result of b.
An optimising compiler may start evaluating b before it has finished evaluating a, if it can prove that the evaluation of b has no side effects, and if it believes that (mostly due to parallelism in the hardware) it is on average faster to evaluate as much in parallel as possible, even if some things are evaluated when it wasn't necessary. But this is not noticable in the results of your code, and will only make the code faster.
This question already has answers here:
Is Short Circuit Evaluation guaranteed In C++ as it is in Java?
(2 answers)
Closed 9 years ago.
main()
{
int k = 5;
if(++k <5 && k++/5 || ++k<=8); // how to compiler compile this statement
print f("%d",k);
}
// Here answer is 7 but why ?
++k < 5 evaluates to false (6 < 5 = false), so the RHS of the && operator is not evaluated (as the result is already known to be false). ++k <= 8 is then evaluated (7 <= 8 = true), so the result of the complete expression is true, and k has been incremented twice, making its final value 7.
Note that && and || are short circuit boolean operators - if the result of the expression can be determined by the left hand argument then the right hand argument is not evaluated.
Note also that, unlike most operators, short circuit operators define sequence points within an expression, which makes it legitimate in the example above to modify k more than once in the same expression (in general this is not permitted without intervening sequence points and results in Undefined Behaviour).
Unlike many questions like this, it appears to me that your code actually has defined behavior.
Both && and || impose sequence points. More specifically, they first evaluate their left operand. Then there's a sequence point1. Then (if and only if necessary to determine the result) they evaluate their right operand.
It's probably also worth mentioning that due to the relative precedence of && and ||, the expression: if(++k <5 && k++/5 || ++k<=8) is equivalent to: if((++k <5 && k++/5) || ++k<=8).
So, let's take things one step at a time:
int k = 5;
if(++k <5 &&
So, first it evaluates this much. This increments k, so its value becomes 6. Then it compares to see if that's less than 5, which obviously produces false.
k++/5
Since the previous result was false, this operand is not evaluated (because false && <anything> still always produces false as the result).
|| ++k<=8);
So, when execution gets to here, it has false || <something>. Since the result of false | x is x, it needs to evaluate the right operand to get the correct result. Therefore, it evaluates ++k again, so k is incremented to 7. It then compares the result to 8, and finds that (obviously) 7 is less than or equal to 8 -- therefore, the null statement following the if is executed (though, being a null statement, it does nothing).
So, after the if statement, k has been incremented twice, so it's 7.
In C++11, the phrase "sequence point" has been replaced with phrases like "sequenced before", as in: "If the second expression is evaluated, every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second expression." Ultimately, the effect is the same though.
In following:
for && "something" is evaluated when first condition is True
for || "something" is evaluated when first condition is False
( (++k <5) && (k++/5) ) || (++k<=8)
( 6 < 5 AND something ) OR something
( False AND something ) OR something
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
False OR 7 < 8
False OR True
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
True
So k comes out to be 7
Initially k is assigned 5, in your declaration, then in following if condition:
++k < 5 && k++ / 5 || ++k <= 8
// ^
// evaluates
Increments k to 6 then its and LHS of && operand evaluates false.
6 < 5 && k++ / 5 || ++k <= 8
// ^ ^^^^^^^
// 0 not evaluates
Then because of Short-Circuit behavior of && operator k++ / 5 will not evaluates.
Short-Circuit behavior of && operator is:
0 && any_expression == 0, so any_expression not need to evaluate.
So above step 2 conditional expression becomes:
0 || ++k <= 8
// ^^^^^^^^
// evaluates
Increments k to 7 then its:
0 || 7 <= 8
because you have ; after if, so no matter whether if condition will evaluates True or False printf() will be called with k = 7.
What would be the output of this program ?
#include<stdio.h>
#include<conio.h>
void main()
{
clrscr();
int x=20,y=30,z=10;
int i=x<y<z;
printf("%d",i);
getch();
}
Actually i=20<30<10, so the condition is false and the value of i should be 0 but i equals 1. Why?
This int i=x<y<z; doesn't work the way you intended.
The effect is int i=(x<y)<z;, where x<yis evaluated first, and the value true is then compared to z.
Pascal points out below that in C the result of the comparison is 1 instead of true. However, the C++ true is implicitly converted to 1 in the next comparison, so the result is the same.
The comparison operators don't work like that. Your program is equivalent to:
i = (x < y) < z;
which is equivalent to:
i = (x < y);
i = i < z;
After the first operation, i == 1. So the second operation is equivalent to:
i = 1 < 10;
You need to rewrite your statement as:
i = (x < y) && (y < z);
The < operator has left-to-right associativity. Therefore x<y<z will do (x<y)<z. The result of the first parenthesis is 1, 1 is smaller than 10, so you'll get 1.
That's not how it works. It's better to see with parenthesis:
int i = (x<y)<z;
Now, first x<y is evaluated. It's true, 20<30, and true is 1 as an integer. 1<z is then true again.
Its precedence is from left to right. Thats is why it is like
20<30 = true
1<10 TRUE
SO FINALLY TRUE
Actually < is left-associative, so first, 20<30 is evaluated (giving 1 usually), then 1 is less than 10.
The output of "1" is correct. This is evaluated as (20<30) < 10, which is 1 < 10, which is 1.
The problem is that you are comparing a boolean value to an integer value which in most cases doesn't make sense.
< is evaulated from left to right, so 20<30 is true, or one, which is less than 10.
The operator < associates from left to right.
So x < y < z is same as ( x < y ) < z
Your expression evaluates as:
( x < y ) < z
= ( 20 < 30 ) < 10
= ( 1 ) < 10
= 1