Go Down

Topic: Can someone explain this? [solved] (Read 1 time) previous topic - next topic


Oct 14, 2012, 02:50 am Last Edit: Oct 14, 2012, 07:16 am by Nick Gammon Reason: 1
I have, what I thought was a pretty straightforward multiplication operation, but....

Code: [Select]
uint32_t p =0;

void setup(){
 p = 15*60*1000;
 Serial.print("Trial 1: "); Serial.println(p);
 p = 15*60;
 p = p*1000;
 Serial.print("Trial 2: "); Serial.println(p);
 p = 15*60;
 p *= 1000;
 Serial.print("Trial 3: "); Serial.println(p);

void loop(){

Trial 1: 4294949792
Trial 2: 900000
Trial 3: 900000

What the f@!#^*?

I can't figure out why Trial 1 give such a wacky number. I thought it was wrap around or maybe the way print works, but as you can see the other trials work just fine. So what is going on? And here I thought I understood this stuff...

-- Thanks!


Literals, like 15, 60, and 1000, are interpreted as ints, in the absence of any directive to the contrary. Nothing in the first calculation is larger than an int, so ints are used in the calculation. The result overflows an int. That the result is stored in a long is irrelevant.

In the second case, 15 * 60 is an int, stored in a long. Then the long is multiplied by an int, which is promoted to a long. The result is a long, which is stored in a long.

The third case is identical to the second. p = p * 1000 is identical to p *= 1000.


15*60 = 900 which fits into a 16-bit integer.
900*1000 = 900000 which doesn't fit. The result is truncated to 16-bit and sign-extended.
900000 = DBBA0 (hex). Truncate to 16 bits = BBA0. This is negative so sign-extend it to 32 bits FFFFBBA0. This value is then stored in p. Converting this as an unsigned 32-bit integer to decimal gives 4294949792.

Don't send me technical questions via Private Message.


Ahhh, that makes a lot of sense.  I knew it had to do something with the size of the variable, just couldn't see how.
Thanks a lot for the help!


So could I do something like this:

p = 15L*60L*1000L to force the operation to use longs for the calculation.


So could I do something like this:

p = 15L*60L*1000L to force the operation to use longs for the calculation.

Yes, you could. And should.

L = long
UL = unsigned long

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131