How to do equal comparison in C or C++? - 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.

Related

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);

Convert while-loop to mathematical formula

I have following loop as a inner loop and try to get rid of it by transforming it into a mathematical formula:
while(!(((aux = a * b) <= c) && (c >= aux + d))) --a;
a, b, c, d and aux are all of type size_t, i.e. unsigned int's
NOTE: a is decremented in every iteration within the loop's body!
I'm totally stuck at this problem. I tried to simplify the loop condition, but failed because of the unsignedness constraint.
As result I just want to get the value of a depending on b, c, d.
Replace aux with a*b at every point, and you get:
!(a * b <= c && c - a * b >= d)
<=> !(a * b <= c && c >= d + a * b)
<=> !(a * b <= c && d + a * b <= c)
If d is greater than c, the second condition will be false and therefore the loop will never terminate. So we can consider only d <= c. The second condition is stricter, so we can focus on that solely:
<=> !(d + a * b <= c)
<=> !( a * b <= c - d)
<=> !( a <= (c - d)/b) // if integer division is used
<=> ( a > (c - d)/b)
Given that you only decrement a, it either needs to fulfil the condition (a <= (c - d)/b) right from the beginning or be less than or equal to (c - d)/b. Overall we get:
a = std::min(a, (c - d)/b);
Let's simplify:
while(!(((aux = a * b) <= c) && (c - aux >= d))) --a;
Drop aux in favor of just a*b:
while(!((a*b <= c) && (c - a*b >= d))) --a;
Rewrite the !(x && y) into !x || !y:
while ((a*b > c) || (c - a*b < d)) --a;
Flip the sign on the second expression:
while ((a*b > c) || (a*b > c - d)) --a;
Which is just:
while (a*b > min(c, c-d)) --a;
Which is to say, find the smallest a such that a*b <= min(c, c-d). Unless it's already smaller than that. So:
a = min(a, min(c, c-d) / b);
Er, given that all the variables are unsigned, obviously min(c, c-d) == c - d, so:
a = min(a, (c-d)/b);

Conditional operators error

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

I need to see if two numbers are multiples

I need to see if two numbers are multiples, and in case they are provide a positive answer, or in case they are't provide a negative one. However, everytime i try to make the prog there are always errors, i'm not sure i'm doing it right.
int A;
int B;
float C;
printf("enter two numbers\n\n");
scanf("%d %d", &A, &B);
C=A/B;
D=A/B;
if (A/B=C) printf ("no");
else printf ("yes");
An obvious error in your code is
if (A/B=C)
// ^ you are using assignment (=) here, not comparison (==)
try
if (A/B==C)
With A,B > 0; A and B are multiple if A % B == 0 or B % A == 0
(% is the modulo operator)
so
bool isMultiple(unsigned int A, unsigned int B)
{
if (A == 0 || B == 0) {
return A == B;
}
// A != 0 && B != 0
return (A % B == 0) || (B % A == 0);
}