I have been trying to simplify this function in a single return A ... B ... C
statement but some cases always slip out. How could this checks be expressed in a logical way (with and
, or
, not
, etc.)?
bool f(bool C, bool B, bool A)
{
if (A)
return true;
if (B)
return false;
if (C)
return true;
return false;
}
CodePudding user response:
bool f(bool C, bool B, bool A)
{
if (A)
return true;
if (B)
return false;
if (C)
return true;
return false;
}
is equivalent to
bool f(bool C, bool B, bool A)
{
if (A)
return true;
else if (B)
return false;
else if (C)
return true;
else
return false;
}
is equivalent to:
bool f(bool C, bool B, bool A)
{
if (A)
return true;
else if (!B)
{
if (C)
return true;
else
return false;
}
else
return false;
}
is equivalent to:
bool f(bool C, bool B, bool A)
{
if (A)
return true;
else if (!B and C)
return true;
else
return false;
}
is equivalent to:
bool f(bool C, bool B, bool A)
{
if (A or (!B and C))
return true;
else
return false;
}
is equivalent to:
bool f(bool C, bool B, bool A)
{
return (A or (!B and C));
}
CodePudding user response:
Make a truth table
A B C return
1 0 0 1
1 0 1 1
1 1 0 1
1 1 1 1
0 0 0 0
0 0 1 1
0 1 0 0
0 1 1 0
Then either you already see how it can be shortened or you just try something, for example:
bool f(bool C, bool B, bool A)
{
return A || (C && not B);
}
Then write a test to see that it always returns the same. I wrote a "manual" test to see that the same truth table is produced:
void test(bool A, bool B, bool C){
std::cout << A << " " << B << " " << C << " " << f(C,B,A) << "\n";
}
int main()
{
for (int A = 1; A >= 0; --A){
for (int B = 0; B<2; B){
for (int C = 0; C<2; C){
test(A,B,C);
}
}
}
}
static std::vector<bool> table{false, true, false, false, true, true, true, true};
which you can then extract the value with
table[4 * A 2 * B C]
Taking this one step further, you could simplify to
242 & (A << 4 B << 2 C)
Both are branchless, which is nice.
CodePudding user response:
Alternative answer:
bool f(bool C, bool B, bool A)
{
if (A)
return true;
if (B)
return false;
if (C)
return true;
return false;
}
You can create a boolean matrix for this:
A | B | C | f(C, B, A) |
---|---|---|---|
f | f | f | f |
f | f | t | t |
f | t | f | f |
f | t | t | f |
t | f | f | t |
t | f | t | t |
t | t | f | t |
t | t | t | t |
The lower half evaluates to if(A)
The remainding entries are these:
B | C | f(C, B, A) |
---|---|---|
f | f | f |
f | t | t |
t | f | f |
t | t | f |
There is only one true-case here: if(!B && C)
To combine these two statements you have to use or
as only one of them needs to evaluate to true
: if((A) || (!B && C))
CodePudding user response:
ya got ternary operators to your rescue ....