Let us see the path which the MCU follows to split 65496 instead of 3072 for the value of i of the following expression:
unsigned int i = 4096*(1700-1400)/400;
1. As the operands 4096, 1700, 1400, and 400 are not declared, the compiler allocates 16-bit storage locations with type int (by default).
2. Now, we have:
unsigned int i = (int)4096*((int)1700 - (int)1400)/(int)400;
i = (int)4096 * ((int)1700 - (int)1400) / (int)400;
Serial.print(i, DEC) ; //shows: 65496
3. Given: unsigned int i = 4096*(1700-1400)/400
int temp = 0x1000 * ((0x06A4 - 0x578))/0x0190
==> temp = 0x1000 * 0x012C /0x0190 //0x12C000/0x0190
==> temp = 0xC000/0x0190
==> temp = 0xD8; //the remainder is discarded; how has 0xD8 come? do the signed division
(1) The upper 8-bit of temp variable is 00000000 – hope you are agreed?
(2) If you carefully look how 80x86 performs 16-bit signed division, you will observe that the when the result is fitted in the AL-register, the upper register AH is filled up with the copies of the sign bit (MSB Bit of the result stored in AL) of the 8-bit quotient. The same rule applies here.
(3) Following the above rule, the upper 8-bit of temp variable of Step-3 is filled up with eight 1s which are the copies of the sign bit of 0xD8 (1101 1000).
4. And now, we have:
int temp = 11111111 11011000
==> int temp = 0xFFD8;
So, when you work with register level codes, you first check if AH-register contains all 1s (0xFF) or not and then you interpret the result accordingly. While working with high level codes, we need to be more literate in programming.
5. Finally, the value of temp is placed into i. As a result we get:
Serial.print(i, DEC); //65496;
Why deos print() method show 65496? It is like this because, you declared i as unsigned variable; where all bits carry positive positional values:
==> 1111 1111 110 1000
==> 1x215 + 1x214 +, … , + 0x20
==> 32768 + 16384 +, …, +0
Remember that the MCU has no knowledge about the meaning of a number. It is the user who gives meaning to his numerical patter. The MCU only knows how to move data from one place to another and knows to manipulate them using arithmetic and logical operations.
To get 3072, you need to declare your expression as shown in Post#1 (i=4096UL*(1700UL-1400UL)/400UL); where, the operands have been declared as unsigned long. Why does Pot#1 need an “unsigned long (32-bit)” data type instead of “unsigned int (16-bit)” is an issue of another analysis.