Why does #define not multiply numbers as expected in arduino/c++?

Viewed 130

Arduino has been giving me unexpected values when trying to multiply numbers together in preprocessor.

e.g.

#define msPerDay (24 * 60 * 60 * 1000)
void setup() {
    Serial.begin(9600);
    Serial.println(msPerDay);
}
void loop() {}

This should output 86400000 but instead I get

23552

In the serial monitor. Also

#define msPerDay (60 * 1000)
void setup() {
    Serial.begin(9600);
    Serial.println(msPerDay);
}
void loop() {}

Should output 60000 but instead prints

-5536

Why is this giving me these unexpected values, what are the rules C++ uses to calculate #define multiplications?

2 Answers

Your int is a 16 bit integer. A 16 bit integer holds values up to 2^15-1 if signed, and 2^16-1 if unsigned.

As those have no suffix, they are all ints, so overflow is undefined.

In practice, your compiler is doing math modulo 2^16.

Odds are that long on your platform is 32 bits. Append an l to those values. It is quite possible that Serial still won't print the value properly if it only prints ints. (It may have a long overload).

Another possibility is that Serial's print method is a 16 bit int and the truncation is going on there, but I doubt it.

In binary 86400000 is 101001001100 101110000000000. To store this number you need 32 bits. But you store this number in 16 bits and you work with 101110000000000, it is 23552.

101001001100 101110000000000
             101110000000000
Related