Navigation



3.6 — Logical operators

While relational operators can be used to test whether a particular condition is true or false, they can only test one condition at a time. Often we need to know whether multiple conditions are true at once. For example, to check whether we’ve won the lottery, we have to compare whether all the numbers we picked match all of the winning numbers. In a lottery with 6 numbers, this would involve 6 comparisons, all of which have to be true. Other times, we need to know whether any one of multiple conditions is true. For example, we may decide to skip work today if we’re sick, if we’re too tired, or if won the lottery in our previous example. This would involve checking whether any of 3 comparisons is true.

Logical operators provide us with this capability.

C++ provides us with 3 logical operators, one of which you have already seen:

Operator Symbol Form Operation
Logical NOT ! !x true if x is false, or false if x is true
Logical AND && x && y true if both x and y are true, false otherwise
Logical OR || x || y true if either x or y are true, false otherwise

Logical NOT

You have already run across the logical NOT operator in the section on boolean values. We can summarize the effects of logical NOT like so:

Logical NOT (operator !)
Right operand Result
true false
false true

If logical NOT’s operand evaluates to true, logical NOT evalutes to false. If logical NOT’s operand evaluates to false, logical NOT evaluates to true. In other words, logical NOT flips a boolean value from true to false or vice-versa.

Logical not is often used in conditionals:

bool bTooLarge = (x > 100); // bTooLarge is true if x > 100
if (!bTooLarge)
    // do something with x
else
    // print an error

One thing to be wary of is that logical NOT has a very high level of precedence. New programmers often make the following mistake:

    int x = 5;
    int y = 7;

    if (! x == y)
        cout << "x does not equal y";
    else
        cout << "x equals y";

This program prints “x equals y”! But x does not equal y, so how is this possible? The answer is that because the logical NOT operator has higher precedence than the equality operator, the expression ! x == y actually evaluates as (!x) == y. Since x is 5, !x evaluates to 0, and 0 == y is false, so the else statement executes!

Note: any non-zero integer value evaluates to true when used in a boolean context. Since x is 5, x evaluates to true, and !x evaluates to false (0). Mixing integer and boolean operations like this can be very confusing, and should be avoided!

The correct way to write the above snippet is:

    int x = 5;
    int y = 7;

    if (!(x == y))
        cout << "x does not equal y";
    else
        cout << "x equals y";

This way, x == y will be evaluated first, and then logical NOT will flip the boolean result.

Rule: If logical NOT is intended to operate on the result of other operators, the other operators and their operands need to be enclosed in parenthesis.

Simple uses of logical NOT, such as if (!bValue) do not need parenthesis because precedence does not come into play.

Logical OR

The logical OR operator is used to test whether either of two conditions is true. If the left operand evaluates to true, or the right operand evaluates to true, the logical OR operator returns true. If both operands are true, then logical OR will return true as well.

Logical OR (operator ||)
Left operand Right operand Result
false false false
false true true
true false true
true true true

For example, consider the following program:

#include <iostream>

int main()
{
    using namespace std;
    cout << "Enter a number: ";
    int nValue;
    cin >> nValue;

    if (nValue == 0 || nValue == 1)
        cout << "You picked 0 or 1" << endl;
    else
        cout << "You did not pick 0 or 1" << endl;
    return 0;
}

In this case, we use the logical OR operator to test whether either the left condition (nValue == 0) or the right condition (nValue == 1) is true. If either (or both) are true, the logical OR operator evaluates to true, which means the if statement executes. If neither are true, the logical OR operator evaluates to false, which means the else statement executes.

You can string together many logical OR statements:

if (nValue == 0 || nValue == 1 || nValue == 2 || nValue == 3)
     cout << "You picked 0, 1, 2, or 3" << endl;

New programmers sometimes confuse the logical OR operator (||) with the bitwise OR operator (|). Even though they both have OR in the name, they perform different functions. Mixing them up can lead to incorrect results.

Logical AND

The logical AND operator is used to test whether both conditions are true. If both conditions are true, logical AND returns true. Otherwise, it returns false.

Logical AND (operator &&)
Left operand Right operand Result
false false false
false true false
true false false
true true true

For example, we might want to know if the value of variable x is between 10 and 20. This is actually two conditions: we need to know if x is greater than 10, and also whether x is less then 20.

#include <iostream>

int main()
{
    using namespace std;
    cout << "Enter a number: ";
    int nValue;
    cin >> nValue;

    if (nValue > 10 && nValue < 20)
        cout << "Your value is between 10 and 20" << endl;
    else
        cout << "You value is not between 10 and 20" << endl;
    return 0;
}

In this case, we use the logical AND operator to test whether the left condition (nValue > 10) AND the right condition (nValue < 20) are both true. If both are true, the logical AND operator evaluates to true, and the if statement executes. If neither are true, or only one is true, the logical AND operator evaluates to false, and the else statement executes.

As with logical OR, you can string together many logical AND statements:

if (nValue1 == 0 && nValue2 == 1 && nValue3 == 4 && nValue4 == 6)
    // do something
else
    // do something else

If all of these conditions are true, the if statement will execute. If any of these conditions are false, the else statement will execute.

Short circuit evaluation

In order for logical AND to return true, both operands must evaluate to true. If the first operand evaluates to false, logical AND knows it must return false regardless of whether the second operand evaluates to true or false. In this case, the logical AND operator will go ahead and return false immediately without even evaluating the second operand! This is known as short circuit evaluation, and it is done primary for optimization purposes.

Similarly, if the first operand for logical OR is true, then the entire OR condition has to evaluate to true, and the second operand does not need to be evaluated.

Short circuit evaluation presents another opportunity to show why operators that cause side effects should not be used in compound expressions. Consider the following snippet:

if (x == 1 && y++ == 2)
    // do something

if x does not equal 1, y++ never gets evaluated! Thus, y will only be incremented if x evaluates to 1, which is probably not what the programmer intended!

New programmers sometimes confuse the logical AND operator (&&) with the bitwise AND operator (&). Even though they both have AND in the name, they perform different functions. Mixing them up can lead to incorrect results.

Mixing ANDs and ORs

Mixing logical AND and logical OR operators in the same expression often can not be avoided, but it is an area full of potential dangers.

Many programmers assume that logical AND and logical OR have the same precedence (or forget that they don't), just like addition/subtraction and multiplication/division do. However, logical AND has higher precedence than logical OR, thus logical AND operators will be evaluated ahead of logical OR operators (unless they have been parenthesized).

As a result of this, new programmers will often write expressions such as nValue1 || nValue2 && nValue3. Because logical AND has higher precedence, this evaluates as nValue1 || (nValue2 && nValue3), not (nValue1 || nValue2) && nValue3. Hopefully that's what the programmer wanted! If the programmer was assuming left to right evaluation (as happens with addition/subtraction, or multiplication/division), the programmer will get a result he or she was not expecting!

When mixing logical AND and logical OR in the same expression, it is a good idea to explicitly parenthesize each operator and it's operands. This helps prevent precedence mistakes, makes your code easier to read, and clearly defines how you intended the expression to evaluate. For example, rather than writing nValue1 && nValue2 || nValue3 && nValue4, it is better to write (nValue1 && nValue2) || (nValue3 && nValue4). This makes it clear at a glance how this expression will evaluate.

De Morgan's law

Many programmers also make the mistake of thinking that !(x && y) is the same thing as !x && !y. Unfortunately, you can not "distribute" the logical NOT in that manner.

De Morgan's law tells us how the logical NOT should be distributed in these cases:

!(x && y) is equivalent to !x || !y
!(x || y) is equivalent to !x && !y

In other words, when you distribute the logical NOT, you also need to flip logical AND to logical OR, and vice-versa!

This can sometimes be useful when trying to make up complex expressions easier to read.

Quiz

Evaluate the following:
1) (true && true) || false
2) (false && true) || true
3) (false && true) || false || true
4) (5 > 6 || 4 > 3) && (7 > 8)
5) !(7 > 6 || 3 > 4)

Quiz answers

1) Show Solution

2) Show Solution

3) Show Solution

4) Show Solution

5) Show Solution

3.7 -- Converting between binary and decimal
Index
3.5 -- Relational operators (comparisons)

26 comments to 3.6 — Logical operators

  • benefited

    Your logical AND section talks about AND but inside table it has “Logical OR (operator ||)”

    [ Thanks for the note Benefited. It has been corrected! -Alex ]

  • Jefferson

    Alex, in the Mixing ANDs and ORs section, in the third paragraph, in the third code snippet, it is either missing a parenthesis, or has one too many, depending on how you look at it.

    [ It had an extra one. Thanks for noticing! -Alex ]

  • [...] 2007 Prev/Next Posts « News — Recent posts box split | Home | 3.6 — Logical operators » Friday, June 15th, 2007 at 10:43 [...]

  • [...] 2007 Prev/Next Posts « 3.6 — Logical operators | Home | 3.8 — Bitwise operators » Sunday, June 17th, 2007 at 11:14 [...]

  • Rob

    I’m probably splitting hairs with this comment, but in the Logical OR section you say the following:

    If the left operand evaluates to true, or the right operand evaluates to true, or both evaluate to true, the logical OR operator returns true.

    However, if the left operand is true, a “short circuit” occurs. In other words, if the left operand is true, the right operand is not even evaluated because the entire statement is already true (so technically, it’s not possible for both operands to evaluate to true in a logical OR). Consider the following code snippet. In this case, “True” will always be printed (the right operand is never evaluated because of the short circuit, even though dividing by zero is illegal):

    if (true || 1/0)
        cout << "True";
    
    • I redid the wording to disambiguate, and added a note about short circuit evaluation of logical OR. Thanks!

      • shinjan

        Just wondering, if this “short circuit” is something which is compiler dependent. There could be many architectures (esp DSP processors) where multiple instructions can be issued on multiple ALUs (VLIW architectures). For e.g. in (x == 1 && y++ == 2), compiler might generate a code for (x==1) and y++ to go in the same cycle. Do you think it is mandatory that compilers have to implement “short circuit”.

  • I had problems making a program that asked the user a question and the user
    had to answer yes or no..so i had to get help on the forum to understand
    something that should have been explaned on this section :]
    if ((x == ‘y’) && (x == ‘e’) && (x == ‘s’) && (”))
    cout << “the anwser here :P” << endl;
    I would more than happy if you would add an example using this too and
    explane why should we use (i would like to know too) and a mistake i did like wrong ‘/0′ and right ” :D stupid computers ^^

  • RonnieTheBear

    Hi Alex. Love the tutorials, especially how you try to relate things back to machine code and whatnot. Truly deepens my understanding. Quick question: is there not an exclusive OR? i.e. if either x OR y are true, but NOT if both are? i.e.

    America has nukes / Russia has nukes / World gets destroyed

    false / false / false
    true / false / true
    false / true / true
    true / true / false [MAD theory ;)]

    Or is there a combination of ANDs and ORs and NOTs to achieve this?

  • Florian

    Hey Ronnie,

    I just thought about your XOR question and came to this solution (since their is no XOR to use directly in c++)

    (!america && russia) || (america && !russia)

    lets just take a logic look behind this:

    //example 1:
    //america false, russia false
    (!false && false) || (false && !false) == false || false == false
    //example 2 & 3:
    //america true, russia false (vice versa is the same result)
    (!true && false) || (true && !false) == true || true == true
    //example 4:
    //america true, russia true
    (!true && true) || (true && !true) == false || false == false

    So basically with only 2 conditions it is easy to handle. How did you manage to pick that example?! :)

    wish you all a nice weekend
    Florian

  • Can you use the logical operators in do…while loops? I try to check an user-entered integer if it’s between 1 and 10. I use the && operator, but I can’t get it to work properly.

    Here’s the code:

    int nInvoer=0;
    do
    	{
    	cout << "Enter number (1 - 10): ";
    	cin >> nInvoer;
    	}
    while (nInvoer < 1 && nInvoer >= 10 ); 
    
    	// Do here if entered value is between 1 and 10.
    

    Whatever value I enter, the program always goes to the next part. If I check either

    nInvoer < 1 

    or

    nInvoer >=10

    it works properly, but I can’t check both at the same time…

    • Never mind… I see my mistake; I should’ve used the || operator.

      Thanks for a great tutorial, Alex!

    • Wintur

      Kaonashi
      “int nInvoer=0;
      do
      {
      cout <> nInvoer;
      }
      while (nInvoer = 10 );

      // Do here if entered value is between 1 and 10.

      Your problem is actually that you have your comparison operators reversed. You want to evaluate between 1 and “&&” 10. As you have it written it will always come up false. This is because you are asking for less than “=”, both can never be true of the same variable, thus it will always be false. If you change your and “&&” to or “||” you will instead be checking if the number entered is not between 1 and 10.

      the correction for this is:

      while (nInvoer >= 1 && nInvoer <= 10 );

      This will check for any number including and between 1 and 10.

  • lsandling

    so how do you get these symbols in Code::Blocks

  • Cyrus

    This is known as short circuit evaluation, and it is done

    primary

    for optimization purposes.

    Should be PRIMARILY :]

  • Rand_Al_Thor

    Heyyy, look at me! I have a nice, polished, streak-free new account! Check out the shine on this baby. :)

    About the quiz questions for this section of the chapter, I know they are meant to test my knowledge of the level of precedence logical AND and logical OR operators have when used in the same expression, but I can’t figure out how to “answer” them after Quiz Question #3.

    I got the first two fine, but I get a little lost when the third one goes into “|| true == false”. I thought it would be “|| false == false” or “|| false == true”, not the other way around?

    I know it seems like a trivial question, but I need to understand this.

  • jimbo

    Hi guys and Alex. First of all thanks a lot for this great tutorial. I understand all the information youv’e provided on logical operators or at least I think I do. However the quiz has totally threw me I don’t understand it at all. If someone could break it down (the quiz) so it’s easier to understand it would be much appreciated. Many thanks in advance.

    • kscarfe

      ^ this.

      I don’t understand the quiz at all. More explanation of the working there would be really helpful. I feel that I understood everything leading up to the quiz, but the format of the quiz was unexpected.

      • Grimercy

        It confused me at first as well. The equality operator is stating that all the preceding (since the previous equality operator) is equivalent to the following. The first problem’s answer could be read like this.

        (true && true) || false

        // (true && true): If one true is true, then both trues are true, so the above statement means the same as (or ==)

        true || false

        // Either true or false must be true, so the above statement evaluates as (or ==)

        true

        If it helps to clarify, ((true && true) || false) == (true || false) == (true). Basically, the goal is to simplify the expression as far as possible, noting the simplifications with ==. Hope that helps!

  • Sakthi

    Hi Alex and team,

    Application of DeMorgan’s Law is NOT explained in the answer of the last quiz question.

    Shouldn’t it be like this ?

    !(7 > 6 || 3 > 4) == !(true || false)
    == (!true && !false) == (false && true) == false

  • Biro Nikolett

    I have some issue with the logical NOT and || parameters.

    My code is this:

    int story(){
    // kiválasztása a névnek és a nem-nek. A név nem befojásoló tényezõ viszont a nem igen
    // mert másképp kell szólítani, hivatkozni rá!
    cout << "Well then i think i can't do anything else. \n I tell one more good night story…\n\n";
    cout << " But lets do it together litle pumkins. First what would be, he or she \? \n";
    cout <> sex ;

    // Fiú szála a történetnek
    if (sex == “he”)
    {
    // névadás a fiúnak
    cout <> character_name; cout << "\n\n";
    // a történet megkezdése
    cout << " ___________________________________________________________________\n";
    cout <<" It was a sunny day when our hero " << character_name << " went out with they wooden sword to play a litle outside.\n";

    };

    // lány szála a történetnek
    if (sex =="she")
    {
    // névadás a lánynak
    cout <> character_name; cout << "\n\n";
    // a történet megkezdése
    cout << " ___________________________________________________________________\n";
    cout <<" It was a sunny day when our heroine " << character_name << " went out with they wooden sword to play a litle outside.\n\n\n";

    };

    if (sex != "he" || sex!="she") {
    cout << "\t Your answer is invalid. Please be sure to tipe in he or she !\n\n\n";

    return story();
    };

    return 0;
    }

    When you tipe in he or she it go and ask for the name as it needed but after giving the name the prograb drop up the error message that you dont tiped he or she. But it catch the problem too if someone dont tipe in he or she he dont let them furter and warn the user.
    I dont know why it is drop out the error when the program once accepted it and let them go forward.

    What i wanted to do is that if the user not give right ansver ( now its he or she ) then return to the beginning after the warning. But right now is either give he or she or give someting else its stuk in a loop. ( this is just a part of my code where are i think the problem should be)

  • Tinkerplus92

    I don’t know if anyone will answer but i don’t understand how Logical NOT works.

    int x = 5;
    int y = 7;

    if (!(x == y))
    cout << "x does not equal to y";
    else
    cout << "x equals to y";

    wouldn't if (!(x == y)) translate to if (!(false))
    and if the variable were equal wouldn't it translate to (!(true)) the conditions in the parentheses would be set either way, my question is how does else get called when it seems the conditions no matter what will always call the first cout. I could just be missing something but I am so confused.

  • eyob worku

    please alex i don’t understand about right and left shift please expan

  • Vaibhav Vardhan

    #include

    int main()
    {
    using namespace std;
    cout <> nValue;

    if (nValue == 0 || nValue == 1)
    cout << "You picked 0 or 1" << endl;
    else
    cout << "You did not pick 0 or 1" << endl;
    return 0;
    }

    In your this program if I enter any letter , the output comes that I have picked 0 or 1………
    can anyone explain me this….

You must be logged in to post a comment.