С этими определениями и предполагая unsigned short
== 16 бит и int
== 16 бит и unsigned long
== 32 бит (обратите внимание, что размер int
важен):
unsigned short a, b;
unsigned long c;
Эти два утверждения будут делать разные вещи:
c = (unsigned long)(a + b);
c = (unsigned long)a + b;
Первый - тот, который вы показали - сначала добавит числа в виде беззнаковых шорт, исключая любое переполнение, и , а затем расширится до беззнакового длинного. Это может быть то, почему вы спрашиваете. Второй приведёт a
к длинному без знака, затем добавит два числа, увеличивая b
до длинного без знака, прежде чем делать сложение.
Вы также можете сделать это:
c = (unsigned long)a + (unsigned long)b;
но это не обязательно, так как наличие одного неподписанного длинного в расчете приведет к автоматическому переходу другого размера с короткого на длинный.
Таким образом:
a = 0x8001;
b = 0x8001;
c = (unsigned long)(a + b); /* c is assigned 0x00000002 */
c = (unsigned long)a + b; /* c is assigned 0x00010002 */
Все это зависит от вашего конкретного компилятора и от размера его переменных. Это конкретно зависит от размера int
вашего компилятора, поскольку все значения автоматически повышаются до int
или unsigned int
во время вычислений. Вы упомянули аппаратное обеспечение с 16-разрядными аккумуляторами, и компиляторы C обычно (но не всегда) используют собственный размер регистра в качестве размера int
, поэтому я предположил int
в качестве 16-разрядных.