Average four 16 bit numbers in Hi-Tech C

Discussion in 'Embedded Systems and Microcontrollers' started by Guinness1759, Jun 8, 2011.

  1. Guinness1759

    Thread Starter Member

    Dec 10, 2010
    Lets say I have temp1, temp2, temp3, and temp4 and they are 16 bit numbers. How do I take the average of them?

    I tried

    volatile unsigned char temp1[2], temp2[2], temp3[2], temp4[2], ave_temp[2];

    ave_temp = (temp1+temp2+temp3+temp4)/4

    but it's giving me a bunch of errors.
  2. RiJoRI

    Well-Known Member

    Aug 15, 2007
    16 bit numbers are usually ints. An int (16 bits) is NOT the same as two (8-bit) chars.

    And if you are adding 4 16-bit ints, you may overflow to the 17th and 18th bits.

    You are trying to do (T1+T2+T3+T4)/4. Another -- and in this case better -- way is (T1/4)+(T2/4)+(T3/4)+(T4/4). But unless the numbers are multiples of four you'll have a rounding error.

    Adding 2 to each number will round up and give a better -- not precise, but better -- answer.

    Work it out on paper. You can use 8- or 4- bit numbers. Remember, dividing by 4 is the same as shifting right twice.

    Guinness1759 likes this.
  3. Guinness1759

    Thread Starter Member

    Dec 10, 2010
    edit: thanks. I think I decided that I'm going to send the data out and do processing on the computer side, that way it can keep track of decimals.
    Last edited: Jun 8, 2011
  4. Papabravo


    Feb 24, 2006
    What decimals?

    You should do the arithmetic using multi-byte precision operations. If you have a 24-bit accumulator then overflow with 16-bit unsigned ints will be no problem. This is probably beyond your capability if you're willing to give up so easily.
    Guinness1759 likes this.
  5. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    All you need is a 32bit variable to add the numbers in;

    Code ( (Unknown Language)):
    2. unsigned long math;  // 32bit variable
    4. math = 0;
    5. math += temp1;
    6. math += temp2;
    7. math += temp3;
    8. math += temp4;
    9. math += 2;  // add half the divisor, is compensation for integer rounding
    10. math = (math / 4);
    11. // at this point math is guaranteed <65536 so it is safe to put back
    12. // into a 16bit variable if needed.
    Guinness1759 likes this.
  6. Alberto

    Active Member

    Nov 7, 2008
    There is a turn around when averaging big numbers that can generate an overflow during addition.

    Here the method:

    Sort in ascending way all the values

    Take the first value (the smallest).

    Subtract the first value from all the other values and add together the differences.

    Average the sum of the difference.

    Add the average to the smallest number you have choosen.

    And the result is the same algebric average of the conventional calculation.


  7. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    Interesting method! But what if the smallest sample is 0 and the other 3 samples are 65535? To average the 3 differences you would still need to add 3* 65535 which still overflows the 16bit accumulator...

    Another way would be to reduce the resolution of the 4 samples to where they could not overflow a 16bit accumulator when added.

    If you divide all the 4 16bit samples by 4 and then add them, the result must still fit in a 16bit accumulator. You can negate the rounding down error by adding 2 to each sample before it is divided by 4, provided every sample is <=65533.

    If you need the full range 0-65535 then you could accumulate the bottom 2 bits of each sample in a second accumulator (8bit size) before they are divided by 4 and then apply it later.
  8. t06afre

    AAC Fanatic!

    May 11, 2009
    In C we have something named Integral Promotion. It may "kick in" in your case. But it will depend on your C compiler. Also drop the divide operation. As it seams your compiler is struggling with this math operation. Instead use the Right shift (>>) operator. The value of a right-shift expression x >> y is x / (2^y). So a divide by 4 is easy to do. And the shift operator is part of the backbone functions in any C compiler
    Last edited: Jun 12, 2011