Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Confused about logical statements in C++

  1. Jul 14, 2012 #1
    Maybe this should belong in the logic section. But since this is C++, ill put it here.

    bool isLeapYear( int y)
    {
    return y%4==0 && y % 100 !=0 || y% 400==0 ;
    }



    They said it returns when y is divisible by 4 but not by 100 unless it is also divisible by 400.

    This is a bit confusing since I thought that statements are binary. that is its either A and(BorC) or (AorB)andC. I mean we get statements like (A and B and B) b/c [A and (B and C)]=[A and B and C]. Same thing for the or operator. But I can't see how (A and B or C) results from a binary logical statement involving two sets.

    Do they mean (y%4==0 && y % 100 !=0 || y% 400==0) is the same as

    (y%4==0) && (y % 100 !=0 || y% 400==0)?

    It would make a lot more sense b/c
    (y%4==0) && (y % 100 !=0 || y% 400==0) is the same as

    (y%4==0 && y % 100 !=0) ||(y%4==0 && y% 400==0)

    which is the same as the statement:y is divisible by 4 but not by 100 unless it is also divisible by 400.
     
  2. jcsd
  3. Jul 15, 2012 #2

    jhae2.718

    User Avatar
    Gold Member

    It works. Let's look at 100 as an example and 800.

    100:

    First, C++ checks if y % 4 == 0. 100 % 4 == 0, so this is true.

    Then, it checks if y % 100 != 0. This is false.

    true AND false is false.

    Then, it checks if y % 400 == 0. 100 % 400 == 100 != 0, so this is false.

    false OR false is false, so the function returns false.

    800:

    First, C++ checks if y % 4 == 0. 800 % 4 == 0, so this is true.

    Then, it checks if y % 100 != 0. This is false.

    true AND false is false.

    Then, it checks if y % 400 == 0. 800 % 400 = 0 == 0, so this is true.

    false OR true is true, so the function returns true.
     
    Last edited: Jul 15, 2012
  4. Jul 15, 2012 #3

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    No! The initial expression is the same as

    (((y % 4 == 0) && (y % 100 != 0)) || (y% 400 == 0))

    A fully parenthesized version of this expression is

    ((((y % 4) == 0) && ((y % 100) != 0)) || ((y% 400) == 0))


    The expression (y%4==0 && y % 100 !=0 || y% 400==0) has no parentheses. There is a lot of ambiguity in that expression. One has to look to the precedence table to resolve this ambiguity. Modulus takes precedence over every other operation in this expression, so the first step in resolving the ambiguity is to group the modulus operations:

    ((y % 4) == 0 && (y % 100) != 0 || (y% 400) == 0)

    Equality and inequality come next in precedence, resolving the expression to

    (((y % 4) == 0) && ((y % 100) != 0) || ((y% 400) == 0))

    Here we have something of the form A && B || C. Logical and takes precedence over logical or, perhaps by way of extension that multiplication takes precedence over addition (2*3+4 is 10, not 14). With this rule, A && B || C is the same as (A && B) || C, or

    ((((y % 4) == 0) && ((y % 100) != 0)) || ((y% 400) == 0))


    That fully-parenthesized version leaves no doubt as to the meaning. My personal rule: Don't rely on the precedence table except where it's patently obvious. 2*3 + 4 is patently obvious. It's 10, no parentheses are needed. Beyond that, it's not obvious. I tend to use lots of parentheses to remove all doubt. On the grounds that arithmetic operators taking precedence over the comparison operators is fairly obvious, I might write the above as

    (((y % 4 == 0) && (y % 100 != 0)) || (y% 400 == 0))


    Note that even though your interpretation is incorrect, it still works here. The reason is that 100 and 400 are multiples of 4.
     
  5. Jul 20, 2012 #4
    Be aware that C and C++ will "short circuit" boolean expressions.

    in the case of

    if (A && B) {...}

    A is checked first, and B will never be evaluated if A is false, which can have side effects if B is a function that updates a state.

    Also be aware the order of execution is not guaranteed under C or C++. Only the order of precedence, and order of binding is guaranteed.

    a+b+c is parsed as a+(b+c) because of right to left binding on the + operator, but the compiler can compute B and C in any order it wants to. Again this can have side effects where B and C are [STRIKE]not simple numbers[/STRIKE] interdependent.
     
    Last edited: Jul 20, 2012
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Confused about logical statements in C++
Loading...