views:

403

answers:

2
+2  Q: 

Overflow In c

Hi,

I have a doubt

When two 16 bit values are added with max values, will there be overflow in the 16 bit machines?

I will elaborate

unsigned short a;
unsigned short b;
unsigned long  c;

c=(unsigned long)(a+b);

Talking about 16 bit processers the accumulator will be of 16 bit size. Will there be an overflow in the above statement? Please clarify.

+8  A: 

Yes, there will be an overflow. The subexpression a + b has type short, and only after it has been evaluated is the result cast to a long. Do this:

c = (unsigned long)a + b;

This will cause a to be cast to a long before the addition takes place, and this in turn will cause b to be cast to a long as well. Hence the addition of two longs takes place, and no overflow will occur.

Stephan202
Whether or not there will be an overflow depends on the size of int in the compiler in question. If int is the same size as unsigned, then you are correct. If int is bigger than unsigned, then the variables will be automatically promoted to unsigned int before the calculation is done.
Eddie
the answer's solution sounds easy, but it does not explain many pitfalls the questioner should be aware of :(
Johannes Schaub - litb
@litb: Is there anything I should add to this answer not already addressed by Eddie? I see you have a lot of rep: feel free to edit this answer.
Stephan202
...now made the answer a community wiki.
Stephan202
i'm fine with how the state of affairs in the thread is currently :) I'll have to learn to write such to-the-point answers like you too. Thinking about it, i guess it's always good for the questioner if there are also short and to-the-point answers, so he first gets the "big picture" of the thing. Others can still write about the gory details :p cheers
Johannes Schaub - litb
+12  A: 

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.

Eddie