If then statement and Boolean Operators Question

Hi I have a question regarding the use of Boolean operators, mainly "or" in an if then statement.
I am writing something where I was previously using the statement-

if (wvform1 == 1 || wvform1 == 4 || wvform1 == 5 || wvform1 == 6 || wvform1 == 7) dblSpd1 = spd1 * 2;

Which is pretty long so I thought I'd simplify it to performing the action if wvform1 is not 2 or 3-

if (wvform1 != 2 || wvform1 != 3) dblSpd1 = spd1 * 2;

As I currently understand, this statment "translates" to "if wvform1 is not equal 2 or if wvform1 is not equal to 3" and these two statements produce equivalent results. Let me know if I've misunderstood something though.
My question is, would I be able to use the following statement as a revision to the smaller statement above?-

if (wvform1 != 2 || 3) dblSpd1 = spd1 * 2;

As I understand, this translates to "if wvform1 is not equal to 2 or 3", maybe a slightly different logical question than the previous.
I have not found answers to this on my own. The code runs as I expect but I am curios if there's something about this logic that is not apparent or if I should avoid this type of language in the future.

This surprises me. In C, you can't take a shortcut like you did. The expression

will always evaluate as true, because a non-zero integer (3 in your case) is always true in boolean context. Anything ORed with true is true.

The previous expression is better written as:

wvform1 < 2 && wvform1 > 3

OR is lazy: as soon as it sees a true value, it doesn't bother going forwards, because it knows that the whole expression will be true anyways. Therefore,

will evaluate as true even when wvform1 == 3, because, in this case, wvform1 != 2 is satisfied and OR happily returns true without asking more questions. AND is lazy too, but in its case, it returns false immediately as soon as it sees anything that is false, because it knows that, in this case, the whole expression will be false, no matter what follows the AND.

This is not equivalent to the previous condition.

(wvform1 != 2 && wvform1 != 3)

is equivalent.

1 Like

correct the first and second statement do produce the same result. But the third one does not, this it because the precedence of the =! operator is higher than the || operator. The third statement is always true it does not matter what value wvform has.

No they don't.

They may, iff wvform1 only varies between 1 and 7 included, but indeed, the two statements are not interchangeable in every case.

What value of wvform makes this anything other than true?
1 true or true = true
2 false or true = true
3 true or false = true
4 true or true = true
5 true or true = true
6 true or true = true
7 true or true = true

Nope. See #7.

I was commenting on this:

first statement:

versus this (second statement, corrected):

You are right, of course, about the statements in the OP's form. Even the two statements on this very post aren't completely the same, depending upon the values that the variable can take.

Ok, given what you explained I see why the code is running correctly but I also see how something like this would get me in trouble in the future. I'll be modifying my statement
Thanks. Your explanation furthered my understanding of the logic at work here.

Oh yes ok, I can see that now. Thank you.

I'd be concerned about the readability of this code.
especially this
if (wvform1 == 1 || wvform1 == 4 || wvform1 == 5 || wvform1 == 6 || wvform1 == 7) dblSpd1 = spd1 * 2;
In doing a test in a program IMHO the code should reflect the context.
So perhaps split the test in two, with useful comments
if (wvform1 < 2) { ..} //this is why
if (wvform1 >3 ) {..} //this has happened

Simplifying that statement was my original reason to change it.
I have now shortened it to a simpler-

if (wvform1 != 2 && wvform1 != 3) dblSpd1 = spd1 * 2;

This feels more readable to me. Would there be any advantage in splitting it up further?

Oh Augustus De Morgan. What would we do without you.

Nope. Assuming you've shown us the entire range of wvform1.

1 Like

Yes, wvform1 is limited from 1-7.

This, or the version with > and <, is the simplest form. You could also do nested ifs if you wanted, but I think they would be less readable.

if (wvform1 != 2)
  if (wvform1 != 3)
    // do stuff

The advantage of nested ifs is that you can easily add else statements at any level of nesting, if you need to.

It depends on what CAUSES the value of wvform to be <2 or >3. And why both different chasnges produce the same result.
Can you write a single simple statement (ie without a logical connective ) that explains

nested if's can also get unreadable - often better use switch - case