The Leap Year Function – Solution

I’ve tackled the leap year program on this blog before. My Month Program series addressed the issue specifically. That code offers the february() function, which returns 28 or 29, depending on whether the current year is the leap year.

Here is the february() function:

int february(int y)
{
	if( y % 4 )
		return(28);
	if( !(y % 100))
	{
		if( y % 400 )
			return(28);
		else
			return(29);
	}
	return(29);
}

The y argument is a year value, but this function has a flaw: If y equals 2000, the function returns 28 days. But if y equals 1900, it also returns 28 days. Effectively, the function always returns 28 days because both 100 and 400 are evenly-divisible by 4, the second block of if statements is never executed.

Yes, sometimes my code is wrong.

The solution for the february() function is easy: Move the first if block below the second. That’s pretty much how I handled the solution to this month’s Exercise with the leap_year() function:

#include <stdio.h>

int leap_year(int year)
{
    /* if the year is divisible by both 100 and
       400, it's a leap year */
    if( (year%400)==0 )
        return(1);
    /* if the year is divisble by 100, it's not
       a leap year */
    if( (year%100)==0 )
        return(0);
    /* check for 4 year interval, which is redundant
       here, but I'll do it anyway */
    if( (year%4) != 0 )
        return(0);
    /* otherwise, it's a leap year */
    return(1);
}

int main()
{
    int y;

    for(y=1584;y<=2100;y+=4)
    {
        if(leap_year(y))
            printf("%d is a leap year!\n",y);
        else
            printf("%d is not a leap year.\n",y);
    }

    return(0);
}

The modulus expression year%n returns zero when year is evenly divisible by n. The ! (NOT) operator reverses this condition, so the result in the various if comparisons proves TRUE.

The leap_year() function takes its argument and first checks to see if year is divisible by 400. If so, it’s a leap year and 1 (TRUE) is returned. I test only 400 here, and not cross-check 100, because all years divisible by 400 are also divisible by 100 (and 4 as well).

Next, if year is divisible by 100, which also means it isn’t divisible by 400 (because that condition has been eliminated), the code returns 0 (FALSE).

Finally, if year isn’t divisible by 4, it’s not a leap year. The comment states that this test is “redundant” because the for loop in the main() function skips every 4 years. So in this code, the leap_year() function’s year%4 test is redundant, but when the function is used in other code, it serves as a valid test.

The code’s output is long, but here are the highlights:

1700 is not a leap year.
1800 is not a leap year.
1900 is not a leap year.
2100 is not a leap year.

Every other year displayed, from 1584 through 2099 (skipping every 4 years), is a leap year. If your solution generated similar results, congratulations!

Now I must go back and fix my Month program . . .

Leave a Reply