Can someone explain this? [solved]

I have, what I thought was a pretty straightforward multiplication operation, but....

uint32_t p =0;

void setup(){
  Serial.begin(9600);
  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(){
}

Yields:
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.

1560 = 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.

Pete

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 = 15L60L1000L to force the operation to use longs for the calculation.

So could I do something like this:

p = 15L60L1000L to force the operation to use longs for the calculation.

Yes, you could. And should.

L = long
UL = unsigned long