Reputation: 16541
can this be done somehow?
if((a || b) == 0) return 1;
return 0;
so its like...if a OR b equals zero, then...but it is not working for me. my real code is:
bool Circle2::contains(Line2 l) {
if((p1.distanceFrom(l.p1) || p1.distanceFrom(l.p2)) <= r) {
return 1;
}
return 0;
}
Upvotes: 5
Views: 77701
Reputation: 3
As you seem to know, in C++, 0
is false and 1
is true. With that in mind, to answer your first question (Code 1):
return !(a && b);
If one of the bools is false then a && b
is false so !(a && b)
is true i.e., 1
, otherwise both a and b are true so a && b
is true so !(a && b)
is false i.e., 0
. You can also do (Code 2)
return !a || !b;
but this performs up to three logical operations whereas the first one performs up to two, which is less. The equivalence of these two expressions is one of De Morgan's laws.
To fix your second code (Code 3):
bool Circle2::contains(Line2 l) {
return p1.distanceFrom(l.p1) <= r || p1.distanceFrom(l.p2) <= r;
}
If you want to avoid the double <= r
(Code 4):
bool Circle2::contains(Line2 l) {
for (auto p : { l.p1, l.p2 }) {
if (p1.distanceFrom(p) <= r) {
return true;
}
}
return false;
};
The for
loop initializes an anonymous array of two values, l.p1
and l.p2
, and checks each one and returns true
immediately if it finds a satisfying point. That means that it short-circuits, like ||
. false
is only returned after both points were found not to satisfy. I would recommend using something like Code 3 because two points to check is simple enough to do with a simple ||
expression. In an alternate scenario where you had to check a lot of points, something like Code 4 would be useful.
Upvotes: 0
Reputation: 36239
If you have lot of that code, you may consider a helping method:
bool distanceLE (Point p1, Point p2, double threshold) {
return (p1.distanceFrom (p2) <= threshold)
}
bool Circle2::contains (Line2 l) {
return distanceLE (p1, l.p1, r) && distanceLE (p1, l.p2, r);
}
If you sometimes have <, sometimes <=, >, >= and so on, maybe you should pass the operator too, in form of a function.
In some cases your intentions by writing this:
if ((a || b) == 0) return 1;
return 0;
could be expressed with an bitwise-or:
if ((a | b) == 0) return 1;
return 0;
and simplified to
return ! (a | b);
But read up on bitwise operations and test it carefully. I use them rarely and especially I didn't use C++ for some time.
Note, that you inverted the meaning between your examples 1 and 2, returning true and false in the opposite way.
And bitwise less-equal doesn't make any sense, of course. :)
Upvotes: 1
Reputation: 20312
Fun with templates:
template <typename T>
struct or_t
{
or_t(const T& a, const T& b) : value1(a), value2(b)
{
}
bool operator==(const T& c)
{
return value1 == c || value2 == c;
}
private:
const T& value1;
const T& value2;
};
template <typename T>
or_t<T> or(const T& a, const T& b)
{
return or_t<T>(a, b);
}
In use:
int main(int argc, char** argv)
{
int a = 7;
int b = 9;
if (or(a, b) == 7)
{
}
return 0;
}
It performs the same comparison you would normally do, though, but at your convenience.
Upvotes: 2
Reputation: 35151
The C++ language specifies that the operands of ||
("or") be boolean expressions.
If p1.distanceFrom(l.p1)
is not boolean (that is, if distanceFrom
returns int, or double, or some numeric class type), the compiler will attempt to convert it to boolean.
For built in numeric type, the conversion is: non-zero converts to true, zero converts to false. If the type of p1.distanceFrom(l.p1)
is of class type Foo
, the compiler will call one (and only one) user defined conversion, e.g., Foo::operator bool()
, to convert the expression's value to bool.
Upvotes: 2
Reputation: 892
You have to specify the condition separately each time:
if (a == 0) || (b == 0))
bla bla;
When you do
if ((a || b) == 0)
bla bla;
it has a different meaning: (a || b) means "if either a or b is non-zero (ie. true), then the result of this expression is true". So when you do (a||b) == 0, you are checking if the result of the previously explained expression is equal to zero (or false).
Upvotes: 2
Reputation: 2030
C++ isn't that smart. You have to do each comparison manually.
bool Circle2::contains(Line2 l) {
if((p1.distanceFrom(l.p1) <= r) || (p1.distanceFrom(l.p2) <= r)) return 1;
return 0;
}
Upvotes: 0
Reputation: 45105
I think you really want something like this:
bool Circle2::contains(Line2 l) {
if((p1.distanceFrom(l.p1) <= r) || (p1.distanceFrom(l.p2) <= r)) return 1;
return 0;
}
Upvotes: 1
Reputation: 1078
Your condition should be (a == 0 || b == 0)
or (p1.distanceFrom(l.p1) <= r || p1.distanceFrom(l.p2)) <= r)
Upvotes: 0
Reputation: 129854
C++ doesn't support any construct like that. Use if (a == 0 || b == 0)
.
Upvotes: 0
Reputation: 108820
You need to write the full expression:
(a==0)||(b==0)
And in the second code:
if((p1.distanceFrom(l.p1)<= r) || (p1.distanceFrom(l.p2)<=r) )
return 1;
If you do ((a || b) == 0)
this means "Is the logical or of a
and b
equal to 0. And that's not what you want here.
And as a side note: the if (BooleanExpression)return true; else return false
pattern can be shortened to return BooleanExpression;
Upvotes: 20