Well cant really answer this because
if (!b && c || a && c)
is not equal to
if ((! a && b) || c)
The truth tables for each are below, abc output:
000 0
001 1
010 0
011 0
100 0
101 1
110 0
111 1
this doesnt match the above
000 0
001 1
010 1
011 1
100 0
101 1
110 0
111 1
test program
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned int a,b,c;
int main ( void )
{
for(a=0;a<2;a++)
for(b=0;b<2;b++)
for(c=0;c<2;c++)
{
printf("%u%u%u ",a,b,c);
if (!b && c || a && c)
{
printf("1\n");
}
else
{
printf("0\n");
}
}
printf("\n");
for(a=0;a<2;a++)
for(b=0;b<2;b++)
for(c=0;c<2;c++)
{
printf("%u%u%u ",a,b,c);
if ((! a && b) || c)
{
printf("1\n");
}
else
{
printf("0\n");
}
}
return(0);
}
Please add more parenthesis to improve the order of operations, and/or post an equivalent equation, then we can talk about how they differ in complexity.
This is equivalent
if (c && (!(!a && b)))
note clang's opinion on this syntax:
fun.c:5:12: warning: '&&' within '||' [-Wlogical-op-parentheses]
if (!b && c || a && c) return(1);
~~~^~~~ ~~
fun.c:5:12: note: place parentheses around the '&&' expression to silence this
warning
if (!b && c || a && c) return(1);
^
( )
fun.c:5:22: warning: '&&' within '||' [-Wlogical-op-parentheses]
if (!b && c || a && c) return(1);
~~ ~~^~~~
fun.c:5:22: note: place parentheses around the '&&' expression to silence this
warning
if (!b && c || a && c) return(1);
^
( )
Using arm as a test target, the answer is not going to be deterministic BTW, it is compiler and target and system dependent on which is faster, less computation, etc. Looks on the surface with an arm and its instruction set features the first solution with gcc is clean and deterministic (no branches).
This will of course change with each compiler and target and also with whatever code surrounds that if statement. (note the version of gcc and clang/llvm can/will create different results).
unsigned int bool1 ( unsigned int a, unsigned int b, unsigned int c )
{
if (!b && c || a && c) return(1);
return(0);
}
unsigned int bool2 ( unsigned int a, unsigned int b, unsigned int c )
{
if (c && (!(!a && b))) return(1);
return(0);
}
//gcc
//00000000 <bool1>:
//0: e2900000 adds r0, r0, #0
//4: 13a00001 movne r0, #1
//8: e3510000 cmp r1, #0
//c: 03800001 orreq r0, r0, #1
//10: e3520000 cmp r2, #0
//14: 03a00000 moveq r0, #0
//18: 12000001 andne r0, r0, #1
//1c: e12fff1e bx lr
//00000020 <bool2>:
//20: e3520000 cmp r2, #0
//24: 0a000005 beq 40 <bool2+0x20>
//28: e2711001 rsbs r1, r1, #1
//2c: 33a01000 movcc r1, #0
//30: e3500000 cmp r0, #0
//34: 01a00001 moveq r0, r1
//38: 13810001 orrne r0, r1, #1
//3c: e12fff1e bx lr
//40: e1a00002 mov r0, r2
//44: e12fff1e bx lr
//clang
//bool1: @ @bool1
//cmp r1, #0
//bne .LBB0_2
//cmp r2, #0
//movne r0, #1
//movne pc, lr
//.LBB0_2: @ %lor.lhs.false
//cmp r2, #0
//movne r2, #1
//cmp r0, #0
//movne r0, #1
//and r0, r0, r2
//mov pc, lr
//bool2: @ @bool2
//mov r3, r0
//cmp r2, #0
//beq .LBB1_2
//mov r0, #1
//cmp r3, #0
//movne pc, lr
//cmp r1, #0
//movne r0, #0
//b .LBB1_3
//.LBB1_2: @ %if.end
//mov r0, #0
//.LBB1_3: @ %return
//mov pc, lr