What happens if I sum negative values to a 16bit register constantly

131 views Asked by At

I am stuck in my project. I am actually finding the average of multiple values. I have ten values to average. The sum is giving the correct result for some time that is I am adding the negative numbers and the result is also negative numbers, but when the values whose average is to be found has high magnitudes then the 16bit register in which the summmation is stored gives positive value. What is going wrong in here.

void SmoothArray()
{ 
    val = 0;
    for(k=0;k<10;k++)
    {
        cc = array[k];
        val += cc; 
    }
    val /= 10; 
}

In this when array has many locations negative the summation is wrong that is positive. C language used. Array is unsigned short, while val is short

4

There are 4 answers

0
chux - Reinstate Monica On

OP's present code is overflowing.

Certainly using a wider integer is the simplest approach as answered by @ouah

Otherwise, to prevent overflow, consider summing in parts. Let us assume variables are type int, int[]

void SmoothArray(void) { 
    val_msds = 0;
    val_lsd = 0;
    for(k=0;k<10;k++) {
        cc = array[k];
        val_msds += cc/10;  
        val_lsd += cc%10;  
    }
    val = val_msds + val_lsd/10; 
}

This approach work well as long as the number of array elements (10 in OP's example) is less than sqrt(INT_MAX).

0
ouah On

What happens if I sum negative values to a 16bit register constantly

You will have undefined behavior. Let's say that for example your int is 16-bit and you are adding the two int value INT_MIN and -1, it will invoke undefined behavior. In most systems you will end up with a positive value.

Use a variable of a wider type to sum your values, for example declare val of type long which guaranteed to be at least 32-bit wide.

0
Daniel Frużyński On

Sum is most probably stored using 2's complement code (see https://en.wikipedia.org/wiki/Two%27s_complement). When you hit the lowest negative value and try to decrement it by one, you will get the largest possible positive value.

Looks that you need to use 32-bit variable to store summed values.

0
Serge Ballesta On

As already said by others, the cause of your problem is an overflow.

Here is another way for taking average of a great number of values with less risk of overflow, provided you can have a hint on the average value. It is based on following formula :

avg(x) = avg(x - hint) + hint

For example, if you know that your values are all between -200 and -300, you could take hint = -250. Now, instead of adding values between -200 and -300, you add values between -50 and +50. The risk of overflow is much weaker, without any loss in precision.

In fact this is commonly used for increasing precision when calculating the average of a great number of floating point values