On Nov 5, 10:54 am, John Bode <john_b...@my-deja.comwrote:
On Nov 5, 12:30 pm, mazwo...@gmail. com wrote:
I'm new here, so excuse me if my style is incorrect. Can anyone come
up with a better method for this calculation?
Code:
int is_leap(int year)
{
switch (year % 19) {
case 0: case 3: case 6: case 8:
case 11: case 14: case 17: return 1;
default: return 0;
}
}
This is part of a calendar program.
Try this:
return (year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0));
I think that's the correct formula (evenly divisible by 400, or evenly
divisible by 4 and not evenly divisible by 100).
/***
Using Mike Lee's Driver (modified a bit by DRC):
------------------------------------------------
OK, if people want to test this for themselves it looks like the code
should be more robust in terms of "clever" optimisers. Try the
following
which sums and prints the number of leap years found:
***/
#include <stdio.h>
#include <time.h>
#define START_YEAR 1582
#define END_YEAR 4000
#define ITERATIONS 100000
typedef unsigned (*leap_func)(un signed);
static unsigned is_a_leap_year1 (unsigned y)
{
return (y % 400u == 0u) ? 1 : (y % 100u == 0u) ? 0u : (y % 4u ==
0u);
}
static unsigned is_a_leap_year2 (unsigned y)
{
return !(y % 4u) && ((y % 100u) || !(y % 400u));
}
static unsigned is_a_leap_year3 (unsigned y)
{
return !(y & 3u) && ((y % 100u) || !(y % 400u));
}
// Kirby
static unsigned is_a_leap_year4 (unsigned y)
{
return y & 3u ? 0u : y % 25u ? 1u : y / 25u & 12u ? 0u : 1u;
}
// Hu
static unsigned is_a_leap_year5 (unsigned y)
{
return (y & 3u) ? 0u : (y % 25u) ? 1u : (y & 15u) ? 0u : 1u;
}
static void test_leap(const char *name, leap_func f)
{
unsigned i,
year;
clock_t start,
end;
unsigned long leap_count = 0;
start = clock();
for (i = 0; i < ITERATIONS; i++) {
for (year = START_YEAR; year <= END_YEAR; year++)
leap_count += f(year);
}
end = clock();
leap_count /= ITERATIONS;
printf("%s leap_count=%lu %.2f seconds\n", name, leap_count,
(double) (end - start) / (double) CLOCKS_PER_SEC) ;
}
int main(void)
{
printf("START_Y EAR=%d END_YEAR=%d ITERATIONS=%d\n ", START_YEAR,
END_YEAR,
ITERATIONS);
test_leap("is_a _leap_year1", is_a_leap_year1 );
test_leap("is_a _leap_year2", is_a_leap_year2 );
test_leap("is_a _leap_year3", is_a_leap_year3 );
test_leap("is_a _leap_year4", is_a_leap_year4 );
test_leap("is_a _leap_year5", is_a_leap_year5 );
return 0;
}
/*
After profile guided optimization, methods 2-5
are all about the same speed, and the "standard"
method is shown to be slower than the others.
Hardware 2.2GHz AMD, compiler MSVC++ 2005 with PGO.
C:\tmp\isleap\R elease>isleap
START_YEAR=1582 END_YEAR=4000 ITERATIONS=1000 00
is_a_leap_year1 leap_count=587 1.92 seconds
is_a_leap_year2 leap_count=587 1.11 seconds
is_a_leap_year3 leap_count=587 1.09 seconds
is_a_leap_year4 leap_count=587 1.11 seconds
is_a_leap_year5 leap_count=587 1.09 seconds
C:\tmp\isleap\R elease>isleap
START_YEAR=1582 END_YEAR=4000 ITERATIONS=1000 00
is_a_leap_year1 leap_count=587 1.92 seconds
is_a_leap_year2 leap_count=587 1.09 seconds
is_a_leap_year3 leap_count=587 1.13 seconds
is_a_leap_year4 leap_count=587 1.09 seconds
is_a_leap_year5 leap_count=587 1.11 seconds
C:\tmp\isleap\R elease>isleap
START_YEAR=1582 END_YEAR=4000 ITERATIONS=1000 00
is_a_leap_year1 leap_count=587 1.92 seconds
is_a_leap_year2 leap_count=587 1.11 seconds
is_a_leap_year3 leap_count=587 1.09 seconds
is_a_leap_year4 leap_count=587 1.11 seconds
is_a_leap_year5 leap_count=587 1.09 seconds
C:\tmp\isleap\R elease>isleap
START_YEAR=1582 END_YEAR=4000 ITERATIONS=1000 00
is_a_leap_year1 leap_count=587 1.92 seconds
is_a_leap_year2 leap_count=587 1.11 seconds
is_a_leap_year3 leap_count=587 1.11 seconds
is_a_leap_year4 leap_count=587 1.09 seconds
is_a_leap_year5 leap_count=587 1.09 seconds
C:\tmp\isleap\R elease>isleap
START_YEAR=1582 END_YEAR=4000 ITERATIONS=1000 00
is_a_leap_year1 leap_count=587 1.92 seconds
is_a_leap_year2 leap_count=587 1.09 seconds
is_a_leap_year3 leap_count=587 1.11 seconds
is_a_leap_year4 leap_count=587 1.11 seconds
is_a_leap_year5 leap_count=587 1.09 seconds
*/