Strange result using serial.print

Hi All,

I am sorry to ask such a newbie question, but i cant figure it out. Here is what i have and what i found

  • variable type unsigned long, 32 bits, can store values between 0 and 2^32
  • Serial.print(76845) correctly prints 76845
  • If i try to Serial.print(5123*15), which is 76845, i get a warning integer overflow in expression (code does compile and it prints 11309 (which turns out to be 2^16 less than the outcome of the product 5123*15) So it seems that one bit is lost in the multiplication I have tried to do the multiplication outside the print command such that

unsigned long temp = (5123*15); Serial.print (temp);

But it doesn't solve the problem

What critical part am i missing? :confused:


I also tried : unsigned long temp = 5123*10; Serial.print(temp);

And the result is 4294952990

if i use: temp = (unsigned int) (5123) * (unsigned int)(10); I get the correct outcome of 51230

if i use: temp = (unsigned int) (5123) * (unsigned int)(15); i get the incorrect outcome of 11309

So i guess the fault is at the multiplication. But why does setting the variable of the outcome to a 4 byte variable AND the other two to unsigned integers, not result in correct outcome?

The result of 512315 is an int which is only promoted to unsigned long after the product overflows. Fix this by forcing one of the terms to unsigned long before the product. e.g using 5123UL15 or 5123*15UL .

An unqualified integer constant is taken to be type int, however big it is. You can qualify a constant as unsigned with U (or u) and long with L (or l), hence 100000ul or 100000L ( I recommend upper case L so not confused with digit 1, but lower case ul as that's easier to see (less confusion), or even uL. )

The type of an expression defaulting to int can truncate values to 16 bit on the Arduino if you are not careful - typecasts are used to instruct the compiler differently: ((long) a) * b or long (a) * b

In C++ you may also be able to say long(233545) and cast the constant, but I might have guessed wrong. Easy to have a play and find out.