misscalculations with unsigned long

I have arduino mega 2560 and using Arduino 1.6.9.

I have trouble with operations like this:

int hour = 9;
unsigned long result = hour * 3600;

result = 32400 THAT is ok

but

int hour = 23;
unsigned long result = hour * 3600;

result = 17264 ??????

and

int hour = 10;
unsigned long result = hour * 3600;

result = 4294937760 ??????

if i try this:

unsigned long result = hour * 100;
result = result * 36;

result = 36000 and this is right.

i cant understand....

what am doing wrong??

An operation involving integers defaults to 16 bits on Arduino.

Declare "hour" as unsigned long, or use "3600UL" as the constant.

or change 3600 to 3600UL which will force the multiplication to be done as unsigned long without needing to allocate 4 bytes to "hour" when one will actually do (hour can be char instead of int).

Pete

The compiler is stupid. It does what you tell it to do. You told it to multiply two ints and put that into an unsigned long.

As already said, you need to multiply two unsigned longs, and then store it.

This is a perfect example of...
https://www.google.com/search?q=why+magic+numbers+are+bad

const unsigned long SecondsPerHour = 3600;

int hour = 9;
unsigned long result = hour * SecondsPerHour;

Oh .. Ok Thanks :slight_smile: :slight_smile: :slight_smile: :slight_smile:

Even better, use the Time library, since all the pre-defined constants are already unsigned long:

/* Useful Constants */
#define SECS_PER_MIN  (60UL)
#define SECS_PER_HOUR (3600UL)
#define SECS_PER_DAY  (SECS_PER_HOUR * 24UL)
#define DAYS_PER_WEEK (7UL)
#define SECS_PER_WEEK (SECS_PER_DAY * DAYS_PER_WEEK)
#define SECS_PER_YEAR (SECS_PER_WEEK * 52UL)
#define SECS_YR_2000  (946684800UL) // the time at the start of y2k

Then you can safely do nifty things like:

unsigned long result = hour * SECS_PER_HOUR;

or

const unsigned long SECS_PER_HALF_WEEK = SECS_PER_DAY * DAYS_PER_WEEK/2;