With these definitions and assuming unsigned short
== 16 bit and int
== 16 bit and unsigned long
== 32 bit (note that the size of int
is important):
unsigned short a, b;
unsigned long c;
These two statements will do different things:
c = (unsigned long)(a + b);
c = (unsigned long)a + b;
The first one -- the one you showed -- will first add the numbers as unsigned shorts, discarding any overflow -- and then expand to an unsigned long. This may be why you're asking. The second will cast a
to an unsigned long, then add the two numbers, expanding b
to an unsigned long as well before doing the addition.
You could also do this:
c = (unsigned long)a + (unsigned long)b;
but it's unnecessary as the presence of one unsigned long in the calculation will cause the other to be automatically promoted from short to long size.
Thus:
a = 0x8001;
b = 0x8001;
c = (unsigned long)(a + b); /* c is assigned 0x00000002 */
c = (unsigned long)a + b; /* c is assigned 0x00010002 */
All of this depends on your specific compiler and on the size of its variables. It depends specifically on the size of an int
on your compiler, as all values are automatically promoted to int
or unsigned int
during calculations. You mentioned hardware with 16 bit accumulators, and C compilers will typically (but not always) use the native register size as the size of int
, which is why I assumed an int
as 16 bits.