Let us first see why you are getting -31912 instead of 1082200? And then we look into the optimum practices that are to be followed (Step-6).
1. Few things to Know:
It is the responsibility of the programmer to know the meanings of data types and then use appropriate data types for the variables.
The programmer must admit that the sign and magnitude of the content of a variable appear after doing some operation on it.
The content of a variable is always saved in memory in bit from.
2. When you multiply aaa*bbb which are 16-bit positive numbers (aaa = 0x0578 = 1400; bbb = 0x0305 = 773), you expect a value of 1082200 in decimal (0x00108358 in hex); but, you have got -31912 in decimal.
3. Because, you have declared the data type of the destination variable (the prod) as 16-bit (int), the compiler has kept only the lower 16-bit of the result (0x8358) into the variable prod.
4. The Serial.print() command has seen that the destination data type is int (it can hold both +v/-ve value) and the MSBit of the incorrect result (0x8358 = 1000 0011 0101 1000) is 1. Accordingly, the incorrect result (0x8358) has been treated in 2's complement form and -31912 is printed (see calculation below to observe how 0x8358 turns into -31912).
-1x215 + 3x162+5x161+8x160
===> -32768 + 768 + 80 + 8
===> - 31912
5. What is the solution?
The solution lies on your judgement. You know that the input numbers are positive 16-bit; so, the multiplication will produce a positive 32-bit result. Therefore, the data type of the destination variable should be declared unsigned long int (to holds only positive value). So, the variable declarations would be:
int aaa = 1400;
int bbb = 773;
unsigned long int prod = aaa * bbb;
Serial.println(prod, DEC); shows: 4294935384 in decimal; FFFF8358 in hex
We have still incorrect decimal result/number on the Serial Monitor. The value should be 1082200 (0x108358) and NOT 4294935384 (0XFFFF8358). What is the reason?
When we have declared the destination variable as 32-bit, the compiler has copied the sign bit (1 = the MSBit of 0x108358 = 1 0000 0011 0101 1000) of the result onto vacant upper bits of the 32-bit variable prod. Now, the variable prod contains 0xFFFF8358 and the print() command shows: 4294935384.
What is the correction factor to be applied to get correct result?
We have to tell the compiler to treat the result as a positive number and not to copy the sign bits at the vacant upper bits of the variable prod.
And also to tell the compiler to use 32-bit buffer while doing the multiplication process as (by default) the IDE for UNO uses 16-bit buffer. This can be done by doing this casting: (unsigned long) on the result. Now, the variable declarations are:
int aaa = 1400;
int bbb = 773;
unsigned long int prod = (unsigned long) aaa * bbb;
Serial.println(prod, DEC); shows: 1082200 (expected result)
6. What is the optimum practice we may follow?
Use appropriate data types and processing buffer size for the input/output variables :
unsigned int aaa = 1400;
unsigned int bbb = 773;
unsigned long int prod = (unsigned long) aaa * bbb; //use 32-bit buffer
Serial.println(prod, DEC); shows: 1082200 (