What is the right way to find the average of two values?

后端 未结 8 1142
北荒
北荒 2021-02-19 00:58

I recently learned that integer overflow is an undefined behavior in C (side question - is it also UB in C++?)

Often in C programming you need to find the average of two

8条回答
  •  别那么骄傲
    2021-02-19 01:04

    Simplest answer if there is only 2 elements to avoid overflow would be:

    (a/2) + (b/2) = average
    

    For more elements, you could use:

    (a/x) + (b/x) + (c/x) + (d/x) ..... = average //x = amount of elements
    

    From a mathematical point of view, this will never reach an overflow if none of the original values has done so previously, as you do not really add them all together, but rather dividing them before adding them together. Thus no result of any operation performed during the calculation, including the result, will ever be larger (to either side of 0) than the largest initial element (assuming you only work with Real Numbers).

    So do the following:

    1. Determine the amount of elements in 'C', let's call it total.
    2. Declare a value to store the average, let's call it average.
    3. Declare a value to store the remainders, let's call it remainder.
    4. Iterate through them and:
      • Divide the current element by the total amount, total.
      • Add the result to the average, average.
      • Add the remainder of the divided values together, remainder.
    5. Divide the remainders as well and add it to the average, average.
    6. Do with the average what you need/intend to.

    This will give you an answer off by a maximum of 1 (Decimal numeric system [base 10]). I don't know C++ yet, so I can only give you an example in C#.

    Pseudo code in C# (just to provide an idea):

    int[] C = new int[20];            //The array of elements.
    int total = C.Length;             //The total amount of elements.
    int average = 0;                  //The variable to contain the result.
    int remainder = 0;                //The variable to contain all the smaller bits.
    foreach (int element in C)        //Iteration
    {
        int temp = (element / total); //Divide the current element by the total.
        average = average + temp;     //Add the result to the average.
        temp = (temp % total);        //Get the remainder (number that was not divided)
        remainder = remainder + temp; //Add remainder to the other remainders.
    }
    average = average + (remainder / total); // Adds the divided remainders to the average.
    

    Compressed C# example:

    int[] C = new int[20];               //The array of elements.
    int total = C.Length;                //The total amount of elements.
    int average = 0;                     //The variable to contain the result.
    int remainder = 0;                   //The variable to contain all the smaller bits.
    foreach (int element in C)           //Iteration
    {
        average += (element / total);    //Add the current element divided by the total to the average.
        remainder += ( element % total); //Add the remainders together.
    }
    average += (remainder / total); //Adds the divided remainders to the total.
    

提交回复
热议问题