Section 6e

Applications of the Rules - Leap Year


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Extending Logical Examples

Calculating for Years

There are several ways to use these logical operators, and you will see many of them in the remainder of this reference. Here is another, more mathematically oriented use of the logical and relational operators together. To qualify as a leap year, the year must be the fourth in a sequence, or divisible by four, with the exception that every fourth century is a leap year (and the other three centuries are not).

In other words, the years 1700, 1800, and 1900 were not leap years, but the year 2000 was. All are divisible by four, but since only every fourth century is a leap year, you need to accept years that are divisible by four and not divisible by 100, or accept divisible by 400. Think about how you would put this into logical terms before looking at the example shown below.

isLeapYear = ( year % 4 == 0 ) && ( year % 100 != 0 ) || ( year % 400 == 0 );

This may be a little hard to analyze just like it is, so break it down as shown below. Readability is always the number one goal.

isAFourthYear = ( year % 4 == 0 );
notACentury = ( year % 100 != 0 );
isAFourthCentury = ( year % 400 == 0 );

isLeapYear = isAFourthYear && notACentury || isAFourthCentury;

Before you jump into the rest of the analysis, note how the modulo operator is being used. The testing process of isAFourthYear simply asks "does the year divide evenly by four (i.e., is the remainder of the division zero)?" The notACentury test asks "does the year NOT divide by 100 (i.e., is the remainder of division by 100 not equal to zero)?".

Finally, isAFourthCentury asks the question "is the year divisible by 400 (i.e., is the remainder zero when divided by 400)?". All these are powerful examples of using the modulo operator for control and decision making conditions. This is another handy item to place in your programming toolbox.

The next thing to note is the order of operations. Relational operators all have the same priority, so the expression above might have been evaluated from left to right. However, due to their application and results, the logical operators have an effective precedence as follows: (not or "!" first; and "&&" second; and "||" third).

Since the first two Boolean variables are ANDed, the AND process will happen first. If that process fails to produce a true result, then the other item (i.e., isAFourthCentury) will be evaluated on its own. Since the OR is between the first two items and the last one, if isAFourthCentury is true, the expression will resolve to true.

Consider the results if the expression had been as shown below.

isLeapYear = isAFourthCentury || isAFourthYear && notACentury;

The values isAFourthYear and notACentury would still have been bound by the AND process, and then they would have been ORed with isAFourthCentury. The only difference is that the isAFourthCentury Boolean would have been evaluated first. Go through the analysis on your own now. If the year qualifies as a leap year by dividing by four, but (AND) not dividing by 100, it is a leap year; OR, if the year qualifies by dividing evenly by 400, then it is a leap year.

Make sure you understand this process before you go on. It may appear complicated, but it is not; each evaluation is as simple as "yes it is" or "no it is not". Once you get the feeling for the testing process here, you will be able to use the relational operators, the logical operators, and even the modulo operator to evaluate much more complex decision making conditions.

The next section will show you how to analyze these expressions with a Truth Table. It is both a way to see what an expression does as well as verifying that it does what you thought it would do (or not). This will be a big step as you will need Truth Tables for most of your Boolean logic work.