Reputation: 1202
I'm trying to this very basic task in C, where I want to define a number of ints in a header file. I've done this like so:
#define MINUTE (60)
#define HOUR (60 * MINUTE)
#define DAY (24 * HOUR)
The problem is that while MINUTE and HOUR return the correct answer, DAY returns something weird.
Serial.println(MINUTE); // 60
Serial.println(HOUR); // 3600
Serial.println(DAY); // 20864
Can someone explain why this happens?
Upvotes: 1
Views: 166
Reputation: 12263
Assuming you have something like
int days = DAY;
or
unsigned days = DAY;
You seem to have 16 bit integers. The max. representable positive value for (signed) 2s complement integers with 16 bits is 32767, for unsigned it is 65535.
So , as 24 * 3600 == 86400
, you invoke undefined behaviour for the signed int
and wrap for the unsigned
(the int
will likely wrap, too, but that is not guaranteed).
This results in 86400 modulo 65356
(which is 2 to the power of 16) which happens to be 20864
.
Solution: use stdint.h
types: uint32_t
or int32_t
to get defined sized integers.
Edit: Using function arguments follows basically the same principle as the initialisers above.
Update: As you clamed, when directly passing the integr constant 86400
to the function, this will have type long
, because the compiler will automatically choose the smallest type which can hold the values. It is very likely that the println
methods are overloaded for long
arguments, so they will print the correct value.
However, for the expression the original types are relevant. And all values 24
, 60
, 60
will have int
type, so the result will also be int
. The compiler will not use a larger type, just because the result might overflow. Use 24L
and you will get a long
result for the macros, too.
Upvotes: 4
Reputation: 5165
20864 = 86400 % 65536
Try storing the value in an int instead of a short.
Upvotes: 0
Reputation: 52622
It looks like you actually managed to dig up an ancient 16 bit compiler (where did you find it? ) Otherwise I'd like to see the code that produces these numbers.
Upvotes: 4