On codecademy there exists a course on C, which includes a project on how to make a calendar. This project includes a boolean function which decides if a given year is a leap year or not. Code:
bool is_leap_year(int year) {
return (year % 4 == 0 && (year % 100 || year % 400 == 0));
}
Given my beginner understanding of operators and return statements, my reading of this code would be: "A given year will be a leap year if it is divisible by 4 AND 100 OR 400." But this would mean that 1992 wouldn't be a leap year, and 1900 would be, which is plainly wrong.
How come then, that when I run the code and input these years, it does return a correct answer?
You appear to think
x || y == 0
means
x == 0 || y == 0
But it doesn't.
x || y == 0
doesn't mean "x or y is equal to zero".
x || y == 0
means "x, or y is equal to zero".
Put more clearly,
x || y == 0
means "(x) is true or (y is equal to zero) is true".
Since true simply means non-zero in C,
x || y == 0
is equivalent to
x != 0 || ( y == 0 ) != 0
That means the formula checks if the year isn't divisible by 100.
year % 4 == 0
Year is divisible by 4.
year % 100
Year isn't divisible by 100.
year % 400 == 0
Year is divisible by 400.
(Year is divisible by 4) and ( (Year isn't divisible by 100) or (Year is divisible by 400) )
How this would normally be stated in English:
It's a leap year if it's divisible by 4, but not by 100. Except years divisible by 400 are leap years.
And here's how things are calculated:
year % 4 == 0 && (year % 100 || year % 400 == 0)
1992 % 4 == 0 && (year % 100 || year % 400 == 0)
0 == 0 && (year % 100 || year % 400 == 0)
1 && (year % 100 || year % 400 == 0)
1 && (year % 100 || year % 400 == 0)
1 && (1992 % 100 || year % 400 == 0)
1 && ( 92 || year % 400 == 0)
1 && 1
1
The right-hand side of ||
isn't evaluated because its left-hand is true.