Simplify logic statement - if-statement

I have this:
if(!A or (A and B)) //pseudocode
I want to negate that if-statement:
This should work:
if(!(!A or (A and B))) //pseudocode
but I believe there is a way to simplify it and it's escaping me at the moment.

Welcome to the world of de-Morgan for boolean algebra followed by simple distribution :
if(!(!A or (A and B))
=> if(!(!A) and !(A and B))
=> if(A and (!A or !B))
=> if((A and !A) or (A and !B))
=> if(A and !B)

If you break it down to a truth table...
A B !A (A and B) A! or (A and B)
0 0 1 0 1
0 1 1 0 1
1 0 0 0 0
1 1 0 1 1
You can see the result is true in all cases except A and !B without having to know/remember any Boolean algebra rules. "Except" is just "not" so... !(A and !B)...
However if writing !A or (A and B) aligns better to the real-world problem you're trying to code leave it like that, unless it's insanely performance critical...

Related

Checking if a given group of integers contains a 0 value

Suppose I have a bunch of integers (10~20) and need to check if any of them equals 0. What's the most efficient way to do it? I don't want to evaluate a giant if(a=0 || b=0 || c=0 ||...) statement. I thought of if(abc... = 0) but if I remember correctly multiplication isn't a very quick process. Are there any other tricks, such as bit wise operations that would work? I'm trying to think as low level as possible to make this super efficient.
I'm pretty sure the fastest and clearest way to do this is with an explicit test:
int has_zero = !a || !b || !c || !d || !e ...;
Because the || and && are short-circuiting operators in C, evaluation stops as soon as the final result is known, so if (for instance) the b variable is zero, that satisfies the expression as true and stops evaluating the rest.
#AbhayAravinda suggested that !(a && b && c && d ...) might be more efficient, but I don't think so; because this is not so much doing an explicit not operation, but a low-level test-against-zero, this is a really easy test for pretty much any architecture to do reliably. I did a quick look at optimized assembler for both versions and there was no clear winner for performance, but I think the first version is clearer.
If every single cycle matters, then check both versions on your platform, but on my 64-bit Intel system, both gcc and clang do in fact generate the same assembly for both versions (with optimizations turned on).
Simple test code:
int a, b, c, d, e, f;
int test_or()
{
return !a || !b || !c || !d || !e || !f;
}
int test_and()
{
return ! (a && b && c && d && e && f);
}
int main()
{
return test_or() | test_and();
}
Compile this with gcc -S -O testfile.c and look at the resulting .s file.
Test each one in turn. Exploit the short-circuiting property of ||; place the variables in descending order of the probability of each being zero:
if (!a/*most likely to be zero*/ || !b || ...){
// one of them is zero
}
Most people give an answer like:
!a || !b || ...
(where a is the most probable one of being zero)
The idea is that, in case a is zero, then the rest of the sequence is not evaluated (because of not being necessary), which is a kind of optimisation, performed by the compiler.
This turns the question into: does your compiler perform this optimisation or not (and in case of "possibly yes", what are the parameters in order to enforce this)?
Can you tell us which compiler (version) you're working with? This might enable us verifying this.
You may look at the assembler output.
The !a || !b || !c || !d || !e || !f will give you a bunch of cmp and je statements. One pair for each variable. Because of boolean short cut evaluation, it may run very fast. Or not.
The maybe better and deterministic solution is using the bitwise AND operator. If one operand is 0, then the result will be 0. So someting like:
if (a & b & c & d & e & f & g & h & i & j & k)
will result in one mov and then and statements for each variable.
So, if the variable that is 0 is in the 2nd half of the if statement, then the bitweise AND will be faster.

Express a truth table using a single if-condition

My code looks like this:
/*
* A B
* 0 0 -> 1
* 0 1 -> 0
* 1 0 -> 0
* 1 1 -> 0
*/
#define A condition_1
#define B condition_2
if (A) {
// do nothing
} else {
if (B) {
// do nothing
} else {
// do something
}
}
Above I've reported the truth table for two conditions where 1 is true and 0 is false, is there a way to express the truth table into a single if-condition?
Your truth table represents a NOR (not or) operation. You can get that easily by combining logical NOT (!) with logical OR (||)
if (!(A || B)) {
}
PS. Please, don't use #define macros. It's very error-prone and tends to bite programmers who use it. Most often there are safer and more readable ways to perform what macro does.
Use:
if (!A && !B) {
// do something
}
Think, your truth table only returns 1 when both conditions are false (0 0 -> 1).
You can use ! in both to invert it.
If there is only one 1 in the table then it's essentially AND operation. If there is only one 0 then it's OR operation. If there are two of both then you can make it an equality operation.
When you know which operation to chose your next step is to figure out which operands should be negated. For AND both operands must turn to 1 to produce 1 (1 AND 1 = 1), so negate those who would otherwise produce 0. For OR it's opposite, negate those who would produce 1 when trying to have 0 a s result (0 OR 0 = 0)
For equality operation bear in mind that bool can either be true or false, so there are only two values. If you try to use something that is not a bool for a logical operand then there would be problems. With that in mind when you want to produce equality negate any of the operands if originally they don't produce correct result (0 == 0 = 1 and also 1 == 1 = 1, if you understand me).
In your particular case we have only one 1 in the table so it's an AND operation. Both operands are 0 for this 1 outcome so we have to negate both of them:
!A && !B

Ocaml, why this code does not work?

let rec prime : int -> bool
= fun n -> let rec f a = if (a = 1) then 1
else if (n mod a) = 0 then 0
else if ((f a-1) = 1) then 1
else 0
in
if ((f n-1) = 1) then true
else false
As you can see from my code, I want to implement a function which can tell given number is prime or not.
I can compile and run this code, but for all X function tell "false".
Why this happens?
Thanks in advance. :)
The expression:
f n-1
is parsed like this:
(f n) - 1
You need to write this:
f (n - 1)
((f n-1) = 1)
f n-1 is equivalent to (f n) - 1, not f (n - 1). So you're taking a number that's either 0 or 1, then subtract 1 from (yielding either -1 or 0) and then seeing whether it's 1, which it can never be.
Note that this wouldn't even have compiled had you made f return a boolean rather than an integer (you can't subtract from a boolean).

Lua if A != (X or Y or Z)?

So I have this function that takes in an integer. But It doesn't work and I suspect that the if statement is not valid, I could not find anything on google regarding the issue, maybe my googling skills just suck.
if mynumber != (0 or 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8) then
print("Please choose an integer number between 1-8")
end
Thanks for any help!!
Correct. That is not how you test things like that. You cannot test multiple values that way.
or requires expressions on either side and evaluates to a single expression. So (0 or 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8) evaluates to 0 and your final expression is just if mynumber != 0 then.
To test multiple values like that you need to use or around multiple comparison expressions.
if (mynumber ~= 0) or (mynumber ~= 1) or (mynumber ~= 2) ... then (also notice ~= is the not-equal operator not !=).
Also be sure to note YuHao's answer about the logic in this line and how to test for this correctly.
Others have pointed the major problems you have, i.e, 0 or 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8 evaluates as 0, the rest is ignored because of short-circuit. You need to test the number with these numbers one by one.
However, there's one last trap. The condition
if mynumber ~= 0 or mynumber ~= 1 then
is always true, because a number is either not equal to 0, in which case mynumber ~= 0 is true; or it is equal to 0, in which case mynumber ~= 1 is true.
The correct logic should be:
if mynumber ~= 0 and mynumber ~= 1 then
Etan's answer explains the behaviour as observed in lua. I'd suggest writing a custom FindIn function for searching:
function FindIn( tInput, Value )
for _ in pairs( tInput ) do
if Value == tInput[_] then return true end
end
return false
end
if FindIn( {1,2,3,4,5,6,7,8}, mynumber ) then
-- ...
end
try this:
In Lua You check if two items are NOT EQUAL by "~=" instead of "!=",
If You compare two items in if statement, then always remember that items should return booleans, so: instead of mynumber != (0 or 1 or...) try something like (mynumber ~= 0) or (mynumber ~= 1) ...
You can do it simple with .... (mynumber have to be integer variable)
if mynumber<0 or mynumber>8 then
print("Please choose an integer number between 1-8")
end

Comparison of int values in an if statement

I had a question in my test paper in which we had to compare the values of int type variables. The first thought that came to my mind was that it was missing the && operator but i am not sure.
int a=2, b=2, c=2;
if(a==b==c)
{
printf("hello");
}
I have a doubt, will the above statement will execute or not in c or c++? Can i have the reason as well.
Thank You
It will execute but with what I believe unexpected results to you.
One of the == will evaluate to a boolean value, which will then be converted to an int and then the second comparison will be performed, comparing an int to either 1 or 0.
The correct statement is a==b && b==c.
For example:
3 == 3 == 3
evaluates to
true == 3
1 == 3
false
a==b==c
is equivalent to
(a == b) == c
The result of a == b is 1 (if true) or 0 (if false), so it will probably not achieve what you expect.
Use a == b && b == c to check if the value of the three objects are equal.
a == b == c is a comparison between c and result of a==b (1 or 0) operation.
use a==b&&b==c.
the condition a==b==c is equivalent to (a==b)==c which will provide the required result iff c==1, else the code will fail.