Conditional operators error - c++

I'm having trouble understanding why the following section of code is returning x and not b.
#include <iostream>
using namespace std;
int main()
{
int x = 12;
int a = 1;
int b = 0;
cout << "answer: " << (x < a && 1 ? a : (x > b && 0 ? b : x)) << endl;
return 0;
}
My working is:
x is NOT lower than a [logical and) 1, move to second set of brackets.
x IS larger than both 0 [logival and] 0 there fore the result should be 'b'.
(as both statement equate to true, shouldn't the Result_if_true statement be the output?)

x > b && 0 does not mean "x is larger than both b and 0".
Instead, it means: "x is larger than b, and 0 is a true statement". The && operator is a logical AND that connects two statements. You cannot use it in the loose way in which the word "and" is used in natural language.

(x < a && 1 ? a : (x > b && 0 ? b : x))
is parsed as
((x < a) && 1) ? a : (((x > b) && 0) ? b : x)
which is the same as
(false && true) ? a : ((true && false) ? b : x)
i.e.
false ? a : (false ? b : x)
i.e.
x

In this expression
(x < a && 1 ? a : (x > b && 0 ? b : x))
there is at first evaluated condition
x < a && 1
It is equal to false because x is not less than a.
So the next expression that will be evaluated is
(x > b && 0 ? b : x)
In this expression condition
x > b && 0
is obviously equal to false
So the value of the whole expression will be the value of subexpression
x
and there will be outputed
answer: 12
Your logical mistake is that expression
x > b && 0
is not equivalent to
( x > b ) && ( x > 0 )
it is equivalent to
( x > b ) && ( 0 )
As expression
( 0 )
is equal to false then and
( x > b ) && ( 0 )
is equal to false

Related

Solving a dp problem from codeforces - Cut Ribbon

I was trying to solve this problem and from the comments section in the editorial, I was directed to the following solution :
#include <bits/stdc++.h>
using namespace std;
#define MAX(a,b,c) max(a,max(b,c))
int n,a,b,c,dp[4001];
int f(int x)
{
if (x == 0) return 0;
if (x < 0 || (x > 0 && x < a && x < b && x < c))
return 0xACCE97ED; // <- **I have doubt here**
if (!dp[x]) dp[x] = MAX(f(x-a),f(x-b),f(x-c)) + 1;
return dp[x];
}
int main()
{
cin >> n >> a >> b >> c;
memset(dp,0,sizeof(dp));
cout << f(n) << endl;
}
I wanted to know:
What is the need of the if statement that returns 0xACCE97ED for the test case:
4000 1 2 3. This test case dosen't work when that specific if statement is missing.
Why specifically 0xACCE97ED is being returned? Because when I tried to return any other number (say 9999), then the output is expected output + 9999.
if (x < 0 || (x > 0 && x < a && x < b && x < c))
return 0xACCE97ED; // -1395746835
Well looking at the dp function, it is basically maximizing values and this specific if statement is saying:
if x < 0
the length of the ribbon you cut is negative (which should be impossible)
or if x > 0 and x < a, b, c which means you can still cut X but all available sizes would result into having a ribbon of negative length
return 0xACCE97ED; return a random negative value which happens to spell out ACCEPTED because this state is invalid
And since the third if statement will try to get the max value, 0xACCE97ED will never be selected as the max value.
0xACCE97ED means "ACCEPTED" in the 1ee7 speech. nothing else specific about this value.
What is the need of the if statement that returns 0xACCE97ED for the test case: 4000 1 2 3
if (x < 0 || (x > 0 && x < a && x < b && x < c))
return 0xACCE97ED; // <- **I have doubt here**
because the function f is recursive, in the next line it calls itself:
if (!dp[x]) dp[x] = MAX(f(x-a),f(x-b),f(x-c)) + 1;
return dp[x];
with a smaller values for x so presumable it will eventually make that if statement true and will return "accepted" (0xACCE97ED).

How does c++ evaluate assignment operators (if statement)

Consider the following
int main() {
int a = 8;
int b = 10;
while (true) {
if (a /= 2 && b < 12) {
b++;
std::cout << b << std::endl;
}
else break;
}
return 0;
}
Now c++ is not my main language, but how does c++ evaluate this if statement?
In this case, when b>=12, the compiler throws the "division by zero" exception, but why?
Now if i wrap the states in parentheses i do not get the exception.
if( (a /= 2) && (b < 12))
Does this have something to do with how c++ evaluates the statements?
If evaluation is not the problem:
I am aware of that
a = (a/2 && b<12)
would not hold either.
P Λ Q does not hold for P Λ ¬Q but the state of P should not be affected? Why is it P gets blamed instead of ¬Q?
if (a /= 2 && b < 12)
is the same as:
if (a /= (2 && b < 12))
so:
2 is evaluated, which is converted to true in the context of an operand to &&. This does not trigger short-circuit evaluation so we continue...
b < 12, which in the case you're talking about is false
So 2 && b < 12 evaluates to false overall
a /= 2 && b < 12 is therefore equivalent to a /= false here, which is equivalent to a /= 0.

Warning: second/third operand of conditional has no effect [-Wunused-value]

std::cout << (abs(b - c) < a) && a < b + c ? 1 : 0;
I want to check if given values can create triangle. I got warnings:
second operand of conditional expression has no effect [-Wunused-value]
third operand of conditional expression has no effect [-Wunused-value]
What's wrong?
Your code translates to:
((std::cout << (abs(b - c) < a)) && a < b + c) ? 1 : 0;
Firstly, operator<< has higher operator precedence than operator&&.
Only the value of abs(b - c) < a will be printed and the (a < b + c ? 1 : 0) part will be AND-ed together with the return value of std::ostream::operator bool.
But the warning is about 1 and 0 not being assigned to anything nor having any side effects, because && precedes the ternary conditional (?:).
The correct code is either:
std::cout << (abs(b - c) < a && a < b + c ? 1 : 0);
// same as std::cout << ((abs(b - c) < a && a < b + c) ? 1 : 0);
or
std::cout << (abs(b - c) < a && (a < b + c ? 1 : 0));
In fact, they're equivalent (apart that one calls operator<< with bool and the other with int), no ternary operator needed:
std::cout << (abs(b - c) < a && a < b + c);

How to do equal comparison in C or C++?

I am just wondering in C or C++, for the expression:
b == c || b == d
Can I do something like:
b == (c || d)
and get the same behavior?
The first expression
b == c || b == d will give you true if b is equal to either c or d.
The second expression
b == (c || d) will check only if b is either equal to 0 or 1 because the output of c || d is binary.
Consider this code:
#include <iostream>
using namespace std;
int main() {
int b=10,c=9,d=10;
cout << (b ==c || b ==d )<<endl;
cout<< ( b == ( c || d)) <<endl;
d=11;
cout << (b ==c || b ==d )<<endl;
cout<< ( b == ( c || d)) <<endl;
return 0;
}
The output is
1
0
0
0
Now you can clearly see that both expressions are not same.
No, operators in C and C++ don't implicitly distribute over subexpressions like that. Evaluation is defined strictly in terms of the direct association of operators with operands. There are no "shortcuts" as you might have in mathematics or English.
If you write code that incorrectly assume such implicit distribution, you're likely to end up with an expression that's syntactically and semantically valid, but that doesn't do what you expect.
The || operator yields a value of 1 or true if either operand is true (non-zero) or a value of 0 or false if both operands are false (equal to zero). And the operands needn't be boolean; they can be of any scalar type. (In C the result is of type int; in C++ it's of type bool.) The expression
b == c || b == d
is equivalent to
(b == c) || (b == d)
and yields a true result if b is equal to c or if b is equal to d. But this expression:
b == (c || d)
computes the value of (c || d), and the tests whether b is equal to the result of that subexpression.
A similar possible source of confusion is that
x < y < z
is not equivalent to
(x < y) && (y < z)
Rather, it's equivalent to
(x < y) < z
where the false or true (in C++) or 0 or 1 (in C) result of x < y is compared to the value of z.

How to combine two if statements into one

Hi I have these two separate if statements, when put like so ;
if (powerlevel <= 0) // <--- ends up having no effect
if (src.health <= 0)
the_thing_to_do();
How do I combine these two if statements into one? is it possible? If so how?
If you want both statements to be true use logical AND
if(powerlevel <= 0 && src.health <= 0)
If you want either of the statements to be true use logical OR
if(powerlevel <= 0 || src.health <= 0)
Both of the above operators are logical operators
Use operator&& if you want both of them to be met (logical AND)
if(powerlevel <= 0 && src.health <= 0) { .. }
or operator|| if you want just one to be met (logical OR)
if(powerlevel <= 0 || src.health <= 0) { .. }
It depends if you want both to evaluate to true...
if ((powerlevel <= 0) && (src.health <= 0)) {
// do stuff
}
... or at least one ...
if ((powerlevel <= 0) || (src.health <= 0)) {
// do stuff
}
The difference being logical AND (&&) or logical OR (||)
Just an aternative if it is meaningful(sometimes).
Both true:
if (!(src.health > 0 || powerlevel > 0)) {}
at least one is true:
if (!(src.health > 0 && powerlevel > 0)) {}
Or if you don't want to use && you can use a Ternary Operator
#include <iostream>
int main (int argc, char* argv[])
{
struct
{
int health;
} src;
int powerlevel = 1;
src.health = 1;
bool result((powerlevel <= 0) ? ((src.health <=0) ? true : false) : false);
std::cout << "Result: " << result << std::endl;
}