Simple C question: multiply with unexpected result


Required code multiplies two numbers and receives unexpected result.
Does anybody know why 82 * 400 would not equal 32800?

Here is a simple test:

void setup() {
      long int test1 = 81 * 400;      //expect 32400
      long int test2 = 82 * 400;      //expect 32800
      Serial.print(" , ");
      //SerialMonitor OUTPUT: 32400 , -32736

I have my suspicions as to what the problem is but I have not been able to fix this by changing datatypes or serial.print specifications.
Anybody know the solution?

Best Regards,

Signed ‘long int’ has the range, defined in <limits.h> ,of ‘LONG_MIN’ to ‘LONG_MAX’.

Thanks, that is what I suspected. But it doesn't help me.

Any ideas on a data type that will have the range? 32800 is rather small anyway.

If signed long int is out of maximum limit, (32800), what wouldn't be?

Code from limits.h:

/* Minimum and maximum values a `signed long int' can hold.
   (Same as `int').  */
#undef LONG_MIN
#define LONG_MIN (-LONG_MAX - 1L)
#undef LONG_MAX
#define LONG_MAX __LONG_MAX__

Best Regards, Nash

Thank you for your insight lloyddean,

after adding #include <limits.h>;

This test shows that the limits are actually much higher than 32800(reasonably).
So it may not be a max limit issue afterall…but something else.

Here is the range test:

void setup() {
      Serial.print(" , ");
      Serial.print(" , ");
      Serial.print(82 * 400,DEC);    //expected 32800.  
      //SerialMonitor OUTPUT: -2147483648 , 2147483647 , -32736

Anyone seen this before?
Any ideas?

Much thanks,

signed long is 31 bits of positive numbers. More than you need. Try this (untested):

long int test2 = 82L * 400L;      //expect 32800


Thanks Andy!

The problem was indeed in the use of a magic token of 400. apparently when multiplying 400 by a long it results in the non long result(makes sense). Not sure what datatype that result is currently, but one with a MAX around 32,500!

So, I see the error of my ways. Adjusting the magic token to 400L solved the problem, as did improving it to a long int membervariable=400;

Thanks again, Nash

Calculations done by the compiler are normally done on (int) variables. So your 400*82 gave you 32800, an arithmatic overflow to -32736, which it is then legal to assign to a long. Using any long value in the expression would "upgrade" the expression to being done with longs, and your problem would be solved. This is one of C's more annoying habits; having a hard and fast rule instead of doing the right thing...

Ah, I see....

Thank you for the clarification. It makes sense. Much was learned from the fix.