[SOLVED]Problem with unsigned long

Hello!

I have a problem with my arduino, calculating numbers.
I am trying to count the number of seconds passed since 00:00..

unsigned long secondsElapsed = ((hour() * 3600) + (minute() * 60) + second)
Serial.print(secondsElapsed);

if hour is between 0-8 it works, but if it's above that, secondsElapsed returns near the maximum value of an unsigned long, that is a 429496xxxx ish number..

I have almost tried anything, calculating just with numbers instead of using time, (hour * (60^2)), ((hour * 1800)*2), and I've tried with normal long, unsigned int, and so on.. But nothing seems to work, can anyone help me? :slight_smile:

Thanks!

Make those constants 'long', so the the expression becomes 'long' and avoid overflow:

unsigned long secondsElapsed = ((hour() * 3600L) + (minute() * 60L) + second);

We're beating one another over these recent posts :slight_smile:

Just FYI, you should remember from your nature/physical science course that one day has 86,400 seconds, far less than what long int or unsigned long so something else was wrong. 8 hour is about 32767, max of signed int, which is what all numerical constants are treated as without specific type case.

Thank you, Anachrocomputer.. It helped :wink:

liudr: I know that the unsigned long, shouldn't have reached the limit.

unsigned long temp = 5 * 3600;

The above code worked, but.

unsigned long temp = 10 * 3600;

didn't.

And neither of them is anywhere near the limit of a long, so I guess the compiler calculates it as a int.

so I guess the compiler calculates it as a int.

Correct. The compiler shoved a 10 into a 16 bit register, and 3600 into a 16 bit register, and multiplied the two registers, resulting in an overflow. The 16 bit value is then moved to a 32 bit memory location.

Had you said:

unsigned long temp = 10UL * 3600UL;

The compiler would have noticed that it needed to use 32 bit registers for the multiply operation, before moving the 32 bit result to a 32 bit memory location.