I made a program using C to find whether the entered year is a leap year or not. But unfortunately its not working well. It says a year is leap and the preceding year is not leap.
#include<stdio.h>
#include<conio.h>
int yearr(int year);
void main(void)
{
int year;
printf("Enter a year:");
scanf("%d",&year);
if(!yearr(year))
{
printf("It is a leap year.");
}
else
{
printf("It is not a leap year");
}
getch();
}
int yearr(int year)
{
if((year%4==0)&&(year/4!=0))
return 1;
else
return 0;
}
After reading the comments i edited my coding as:
#include<stdio.h>
#include<conio.h>
int yearr(int year);
void main(void)
{
int year;
printf("Enter a year:");
scanf("%d",&year);
if(!yearr(year))
{
printf("It is a leap year.");
}
else
{
printf("It is not a leap year");
}
getch();
}
int yearr(int year)
{
if((year%4==0)
{
if(year%400==0)
return 1;
if(year%100==0)
return 0;
}
else
return 0;
}
Your logic to determine a leap year is wrong. This should get you started (from Wikipedia):
if year modulo 400 is 0
then is_leap_year
else if year modulo 100 is 0
then not_leap_year
else if year modulo 4 is 0
then is_leap_year
else
not_leap_year
x modulo y
means the remainder of x
divided by y
. For example, 12 modulo 5 is 2.
Most efficient leap year test:
if ((year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0))
{
/* leap year */
}
This code is valid in C, C++, C#, Java, and many other C-like languages. The code utilizes a single TRUE/FALSE expression that consists of three separate tests:
- 4th year test:
year & 3
- 100th year test:
year % 25
- 400th year test:
year & 15
A complete discussion of how this code works appears below, but first a discussion of Wikipedia's algorithm is called for:
Wikipedia algorithm is INEFFICIENT/UNRELIABLE
Wikipedia has published a pseudo-code algorithm (See: Wikipedia: Leap year - Algorithm) that has been subjected to constant editing, opinion, and vandalism.
DO NOT IMPLEMENT WIKIPEDIA ALGORITHM!
One of the longest-standing (and inefficient) Wikipedia algorithms appeared as follows:
if year modulo 400 is 0 then
is_leap_year
else if year modulo 100 is 0 then
not_leap_year
else if year modulo 4 is 0 then
is_leap_year
else
not_leap_year
The above algorithm is inefficient because it always performs the tests for the 400th year and 100th year even for years that would quickly fail the "4th year test" (the modulo 4 test)—which is 75% of the time! By re-ordering the algorithm to perform the 4th year test first we speed things up significantly.
"MOST-EFFICIENT" PSEUDO-CODE ALGORITHM
I provided the following algorithm to Wikipedia (more than once):
if year is not divisible by 4 then not leap year
else if year is not divisible by 100 then leap year
else if year is divisible by 400 then leap year
else not leap year
This "most-efficient" pseudo-code simply changes the order of tests so the division by 4 takes place first, followed by the less-frequently occurring tests. Because "year" does not divide by four 75-percent of the time, the algorithm ends after only one test in three out of four cases.
NOTE: I have fought various Wikipedia editors to improve the algorithm published there, arguing that many novice—and professional—programmers quickly arrive at the Wikipedia page (due to top search engine listings) and implement the Wikipedia pseudo-code without any further research. Wikipedia editors repudiated and deleted every attempt I made to improve, annotate or even merely footnote the published algorithm. Apparently, they feel finding efficiencies is the programmer's problem. That may be true, but many programmers are too hurried to perform solid research!
DISCUSSION OF "MOST-EFFICIENT" LEAP YEAR TEST
Bitwise-AND in place of modulo:
I have replaced two of the modulo operations in the Wikipedia algorithm with bitwise-AND operations. Why and how?
Performing a modulo calculation requires division. One doesn't often think twice about this when programming a PC, but when programming 8-bit microcontrollers embedded in small devices you may find that a divide function cannot be natively performed by the CPU. On such CPUs, division is an arduous process involving repetitive looping, bit shifting, and add/subtract operations that is very slow. It is very desirable to avoid.
It turns out that the modulo of powers of two can be alternately achieved using a bitwise-AND operation (see: Wikipedia: Modulo operation - Performance Issues):
x % 2^n == x & (2^n - 1)
Many optimizing compilers will convert such modulo operations to bitwise-AND for you, but less advanced compilers for smaller and less popular CPUs may not. Bitwise-AND is a single instruction on every CPU.
By replacing the modulo 4
and modulo 400
tests with & 3
and & 15
(see below: 'Factoring to reduce math') we can ensure that the fastest code results without using a much slower divide operation.
There exists no power of two that equals 100. Thus, we are forced to continue to use the modulo operation for the 100th year test, however 100 is replaced by 25 (see below).
Factoring to simplify the math:
In addition to using bitwise-AND to replace modulo operations, you may note two additional disputes between the Wikipedia algorithm and the optimized expression:
modulo 100
is replaced bymodulo 25
modulo 400
is replaced by& 15
The 100th year test utilizes modulo 25
instead of modulo 100
. We can do this because 100 factors out to 2 x 2 x 5 x 5. Because the 4th year test already checks for factors of 4 we can eliminate that factor from 100, leaving 25. This optimization is probably insignificant to nearly every CPU implementation (as both 100 and 25 fit in 8-bits).
The 400th year test utilizes & 15
which is equivalent to modulo 16
. Again, we can do this because 400 factors out to 2 x 2 x 2 x 2 x 5 x 5. We can eliminate the factor of 25 which is tested by the 100th year test, leaving 16. We cannot further reduce 16 because 8 is a factor of 200, so removing any more factors would produce a unwanted positive for a 200th year.
The 400th year optimization is greatly important to 8-bit CPUs, first, because it avoids division; but, more important, because the value 400 is a 9-bit number which is much more difficult to deal with in an 8-bit CPU.
Short-circuit Logical AND/OR operators:
The final, and most important, optimization used are the short-circuit logical AND ('&&') and OR ('||') operators (see: Wikipedia: Short-circuit evaluation), which are implemented in most C-like languages. Short-circuit operators are so named because they do not bother to evaluate the expression on the right side if the expression on the left side, by itself, dictates the outcome of the operation.
For example: If the year is 2003, then year & 3 == 0
is false. There is no way that the tests on the right side of the logical AND can make the outcome true, so nothing else gets evaluated.
By performing the 4th year test first, only the 4th year test (a simple bitwise-AND) is evaluated three-quarters (75 percent) of the time. This speeds up program execution greatly, especially since it avoids the division necessary for the 100th year test (the modulo 25 operation).
NOTE ON PARENTHESES PLACEMENT
One commenter felt parentheses were misplaced in my code and suggested the sub-expressions be regrouped around the logical AND operator (instead of around the logical OR), as follows:
if (((year & 3) == 0 && (year % 25) != 0) || (year & 15) == 0) { /* LY */ }
The above is incorrect. The logical AND operator has higher precedence than logical OR and will be evaluated first with or without the new parentheses. Parentheses around the logical AND arguments has no effect. This might lead one to eliminate the sub-groupings entirely:
if ((year & 3) == 0 && (year % 25) != 0 || (year & 15) == 0) { /* LY */ }
But, in both cases above, the right side of the logical OR (the 400th year test) is evaluated almost every time (i.e., years not divisible by 4 and 100). Thus, a useful optimization has been mistakenly eliminated.
The parentheses in my original code implement the most optimized solution:
if ((year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0)) { /* LY */ }
Here, the logical OR is only evaluated for years divisible by 4 (because of the short-circuit AND). The right side of the logical OR is only evaluated for years divisible by 4 and 100 (because of the short-circuit OR).
NOTE FOR C/C++ PROGRAMMERS
C/C++ programmers might feel this expression is more optimized:
if (!(year & 3) && ((year % 25) || !(year & 15))) { /* LY */ }
This is not more optimized! While the explicit == 0
and != 0
tests are removed, they become implicit and are still performed. Worse, the code is no longer valid in strongly-typed languages like C# where year & 3
evaluates to an int
, but the logical AND (&&
), OR (||
) and NOT (!
) operators require bool
arguments.
int isLeapYear(int year)
{
return (year % 400 == 0) || ( ( year % 100 != 0) && (year % 4 == 0 ));
}
This could be the right solution. Algorithm given on Wikipedia is not right.
-(BOOL)isLeapYear: (int)year{
if(year%4==0){
if(year%100!=0){
return YES;
}
else if(year%400!=0){
return YES;
}
else return NO;
}
else return NO;
}
Although the logic that divides by 400 first is impeccable, it is not as computationally efficient as dividing by 4 first. You can do that with the logic:
#define LEAPYEAR(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
This divides by 4 for every value, but for 3/4 of them, the testing terminates there. For the 1/4 that pass the first test, it then divides by 100, eliminating 24/25 values; for the remaining 1 out of a 100, it divides by 400 too, coming up with a final answer. Granted, this is not a huge saving.
From Wikipedia article on Leap year:
if (year modulo 4 is 0) and (year modulo 100 is not 0) or (year modulo 400 is 0)
then is_leap_year
else
not_leap_year
The problem with your code is that you are returning a non-zero value from yearr
if you think that the year is a leap year. So you don't need the !
in your if statement.
http://www.wwu.edu/depts/skywise/leapyear.html
Leap Year Rules
There is a leap year every year whose number is perfectly divisible by four - except for years which are both divisible by 100 and not divisible by 400. The second part of the rule effects century years. For example; the century years 1600 and 2000 are leap years, but the century years 1700, 1800, and 1900 are not. This means that three times out of every four hundred years there are eight years between leap years.
if(year%400 ==0 || (year%100 != 0 && year%4 == 0))
{
printf("Year %d is a leap year",year);
}
else
{
printf("Year %d is not a leap year",year);
}
Change it like above. Also read this.
#include void main(void) { int year; printf("Enter a year to check if it is Leap Year\n"); scanf("%d",&year); if(year%400==0) /* Why mod 400 */ printf("%d is a Leap Year\n",year); else if(year%100==0) /* Why mod 100 */ printf("%d is not a Leap Year\n",year); else if(year%4==0) printf("%d is a Leap Year\n",year); else printf("%d is not a Leap Year\n",year); }
I used this code:
#include <stdio.h>
int main()
{
int yr;
printf ("Enter a year \n");
scanf ("%d", &yr);
if (yr%400 == 0)
printf("\n LEAP YEAR.");
else if (yr%4==0 && yr%100!=0)
printf("\n LEAP YEAR.");
else
printf ("\n NOT LEAP YEAR.");
}
As other have also mentioned condition for leap year is not correct. It should:
int yearr(int year)
{
if(((year%4 == 0) && (year%100 !=0)) || (year%400==0))
return 1;
else
return 0;
}
Read it here how to check leap year in C.
Kevin's answer provides an optimal 8 operation test (with XOR using constants) but if you are looking for something a bit more readable, try this 9 operation test.
year % 4 == 0 && !((year % 100 == 0) ^ (year % 400 == 0))
Truth table for (year % 100 == 0) ^ (year % 400 == 0)
(year % 100 == 0) ^ (year % 400 == 0)
100 doesnt divide year . F
only 100 divides year . T
100 and 400 divides year . F
Now !(year % 100 == 0) ^ (year % 400 == 0)
gives what you want.
Calculate max/last day for month: 1..12, year: 1..3999
maxDays = month == 2 ?
28 + ((year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0)) :
30 + ((month & 1) ^ (month > 7));
#define is_leap(A) !((A) & 3)
Just make sure you don't enter negative year :)
来源:https://stackoverflow.com/questions/3220163/how-to-find-leap-year-programatically-in-c