Simplifying (and make it more legible) logic condition - c

I am looking for help in making this logic more legible. Assume each alphabet letter is a compare statement (e.g TRUE == a.foo). Each alphabet is about 30 char long statements.
if ( ((a || b)
&& (c || d)) ||
((e || f)
&& (g || h)) )
Any suggestions?

Decompose it.
int ab = a || b,
cd = c || d,
ef = e || f,
gh = g || h,
firstThing = ab && cd,
secondThing = ef && gh;
if (firstThing || secondThing)

Try lining up the subexpressions in groups, lining up the parenthesis:
if (((a || b) && (c || d)) ||
((e || f) && (g || h)))

In order for the conditions to align properly and the logic operator to stand out, I would use this style:
if (((a || b) && (c || d))
|| ((e || f) && (g || h))
...
|| ((u || v) && (w || x))) {
/* handle the successful test */
} else {
/* handle the other cases */
}

There are a few variations of this, but here's one way that I think is pretty clear:
if
(
(
(a || b)
&&
(c || d)
)
||
(
(e || f)
&&
(g || h)
)
)

Related

Why no brackets needed among conditions in if sentence?

int num;
scanf("%d", &num);
if (num % 4 == 0 && num%100 != 0 || num % 400 == 0)
printf("%d", 1);
else
printf("%d", 0);
In this logic, I found I do not need to do () in AND condition which is in front of OR condition.
if (*(num % 4 == 0 && num%100 != 0)* || num % 400 == 0)
It's only needed if (num % 4 == 0 && num%100 != 0 || num % 400 == 0) without () in front of OR condition.
so, it seems (A && B || C) works like ((A && B) || C)
but it seemed it could work as (A && (B || C)) condition.
Why is () not needed in this situation? A and B condition are automatically grouped from the beginning?
All operators in C (and in fact all languages) have what's called operator precedence which dictates which operands are grouped first.
The logical AND operator && has a higher precedence than the logical OR operator ||, which means that this:
A && B || C
Is the same as this:
(A && B) || C
So if you want B || C to be grouped together, you need to explicitly add parenthesis, i.e.:
A && (B || C)
Parentheses decide order of operations, if you move the parentheses around you may change what the output is. In the same way that (A + B) / C is different from A + (B / C) but still a valid equation.
See Order of Operations in C
Logical AND has higher priority than OR:
https://en.cppreference.com/w/c/language/operator_precedence
dg

Comparing GLKMatrix4

How would you normally compare two GLKMatrix4, or at least check if on is the identity matrix?
A cursory search of GLKMatrix4.h shows no util function, and I was feeling silly checking every field manually like this:
static BOOL GLKMatrix4EqualToMatrix4(GLKMatrix4 a, GLKMatrix4 b)
{
return
a.m00 == b.m00 &&
a.m01 == b.m01 &&
a.m02 == b.m02 &&
a.m03 == b.m03 &&
a.m10 == b.m10 &&
a.m11 == b.m11 &&
a.m12 == b.m12 &&
a.m13 == b.m13 &&
a.m20 == b.m20 &&
a.m21 == b.m21 &&
a.m22 == b.m22 &&
a.m23 == b.m23 &&
a.m30 == b.m30 &&
a.m31 == b.m31 &&
a.m32 == b.m32 &&
a.m33 == b.m33;
}
You can transform it into string and then compare using this function NSStringFromGLKMatrix4
You can do:
static BOOL GLKMatrix4EqualToMatrix4(GLKMatrix4 a, GLKMatrix4 b) {
return memcmp(a.m, b.m, sizeof(a.m)) == 0;
}
Because memcmp is usually highly optimized for specific architectures, it should be the fastest, and cleanest approach.
See Why is memcmp so much faster than a for loop check? for discussion on memcmp.

Get rid of "if" - Boolean Logic

I was wondering if we could get rid of all the "if" statements only by using boolean logic.
int main() {
int a,b,c,d;
char e;
scanf("%d %d %d", &a, &b, &c);
scanf("%d", &d);
if (d == 0)
{
e = 'O'*((a+b == c) || (a+c == b) || (b+c == a));
e += (e == 0)*'X';
printf("%c\n",e);
}
if (d == 1)
{
e = 'O'*((a*b == c) || (a*c == b) || (b*c == a));
e += (e == 0)*'X';
printf("%c\n",e);
}
}
So far I've been able to replace
if ((a+b == c) || (a+c == b) || (b+c == a))
{
e = '0';
}
else
{
e = 'X';
}
by
e = 'O'*((a+b == c) || (a+c == b) || (b+c == a));
e += (e == 0)*'X';
is there any way to get rid of the lines
if (d == 0)
and
if (d == 1)
using the same logic?
As you wish, no if-statement left:
!d && (
(e = 'O'*((a+b == c) || (a+c == b) || (b+c == a))),
(e += (e == 0)*'X'),
printf("%c\n",e)
);
d-1 || (
(e = 'O'*((a*b == c) || (a*c == b) || (b*c == a))),
(e += (e == 0)*'X'),
printf("%c\n",e)
);
I abused short-circuiting of ||, && and the comma-operator ,.
Anyway, if you want to see the masters in obfuscation, look at
The International Obfuscated C Code Contest .
Speaking about the motivation of this, it is a good thing if you are concerned about efficiency, as conditional branches are very time-consuming (this is the reason there are some complicated mechanisms for branch prediction). But it is not a good practice in usual code, as it might be very hard to understand for your reader, so your code becomes very hard to maintain. Also, as you are a beginner, it is a very good exercise.
Now, keep in mind that there is always a way. It is worth mentioning that you have a combination of logical, bitwise and arithmetic operation. It could be done purely with bitwise operations.
Let's try to make it using just bitwise operations. Assume your code is:
if (d == 0)
e = A;
if (d == 1)
e = B;
, where A and B are those 2 values you compute for e.
Firstly, extend the last significant bit to all of the d's bits (so if d is 1, it should be 0xFFFFFFFF and if it is 0, it should be 0x00000000). Then, do the operation. I splitted them into multiple lines, but it could be done more compact.
d = d << 1 + d;
d = d << 2 + d;
d = d << 4 + d;
d = d << 8 + d;
d = d << 16 + d;
e = (B & d) || (A & ~d);
Note that here I assume an int is 32 bits, which is not very portable. But, it is just an exercise.

HCL three input odd parity

I have three inputs: a,b, and c. If my output is 1 then there are odd number of inputs with 1. Otherwise it is 0.
I have tried so far (a && b && c) || (!a && !b && !c), (a && b && c) || (!a && b && c), (a && c) || (b&& !c) and quite a few others. How can I do this?
How about a ^ b ^ c?
If only basic logic operators are allowed, you can use this
((a && b || !c) || (!a && !b || !c)) && (!a || !b || c) && (a || b || c)
as dbaupp commented, just equivalent transformation.

"lvalue required as left operand of assignment " error

The following code produces a "lvalue required as left operand of assignment"
if( c >= 'A' && c <= 'Z' || c = " " || c = ",") {
I assume I'm writing this wrong, what is wrong? and how would I write it correctly?
You should use single quotes for chars and do double equals for equality (otherwise it changes the value of c)
if( c >= 'A' && c <= 'Z' || c == ' ' || c == ',') {
Furthermore, you might consider something like this to make your boolean logic more clear:
if( (c >= 'A' && c <= 'Z') || c == ' ' || c == ',') {
Although your boolean logic structure works equivalently (&& takes precedence over ||), things like this might trip you up in the future.
equality is ==, = is assignment. You want to use ==. Also "" is a char*, single quotes do a character.
Also, adding some parens to your condition would make your code much easier to read. Like so
((x == 'c' && y == 'b') || (z == ',') || (z == ' '))
= is the assigning operator, not the comparing operator. You are looking for ==.
Personally, I prefer the minimalist style:
((x == 'c' && y == 'b') || (z == ',') || (z == ' '))
( x == 'c' && y == 'b' || z == ',' || z == ' ' )
or
( x == 'c' && y == 'b' ? z == ',' : z == ' ' )
against
( x == 'c' && y == 'b' ? z == ',' : z == ' ')

Resources