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

*/