Go Down

Topic: [SOLVED]Problem with unsigned long (Read 636 times) previous topic - next topic

Lasse

Aug 18, 2011, 08:05 pm Last Edit: Aug 18, 2011, 08:33 pm by Lasse Reason: 1
Hello!

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

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? :)

Thanks!

Anachrocomputer

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

Code: [Select]
unsigned long secondsElapsed = ((hour() * 3600L) + (minute() * 60L) + second);

liudr

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

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.

Lasse

Thank you, Anachrocomputer.. It helped ;)

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

Code: [Select]

unsigned long temp = 5 * 3600;

The above code worked, but.
Code: [Select]

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.

PaulS

Quote
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:
Code: [Select]
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.

Go Up