Home > Software engineering >  Finding average of a given array
Finding average of a given array

Time:12-24

I am trying to answer the following:

Implement a function that is given an array of integers and the number of items. It should return the rounded (to the nearest integer) average of the numbers.

This is my code:

#include <stddef.h>
int CalculateAverage (const int array[], size_t size)
{
    
    int i;
    long total;
    float convert;
    int temp = 0;
    int average;
    if (size == 0)
    {
        return 0;
    }
    for (i=0; i<size; i  )
    {
        temp = total;
        total = temp   array[i];
    }
    
    convert = total;
    convert = convert / size;
    average = (convert > 0) ? convert   0.5 : convert - 0.5;
    
    return average;
}

I can't use any functions. When I run the test on our class tutorial app I get (every time with different inputs):

Testing Report:
Running test: CalculateAverage(size=11)  --  Passed
Running test: CalculateAverage(size=13)  --  Failed

Done

I am not sure where is my mistake. I think it is related to negative/positive inputs. any suggestions?

CodePudding user response:

Main issue: Uninitialized object

Below is bad as total is read, but not yet initialized nor assigned. @abelenky

long total;
 ...
    temp = total;

long not that wide

Good that OP is trying to accumulate the sum in a wider type, yet long is not certainly twice as wide as int *1. Consider long long or intmax_t. Even those are not certain to be wider, yet commonly are wider.

Wrong rounding

convert 0.5 not needed as prior convert / size already rounded. Floating point math not needed. Conversion to float risks losing precision. Use of double math with float object is curious.

Wrong type

Iterator i should match type of size.

Good use of const and size==0 detection


Proposed fix

#include <inttypes.h>
#include <stddef.h>

int CalculateAverage (const int array[], size_t size) {
  if (size == 0) {
    return 0;
  }
  intmax_t sum = 0;
  for (size_t i = 0; i<size; i  ) {
    sum  = array[i];
  }

  // Form a rounded average by subtracting/adding half the size before the division.
  // For handling ties and round to even obliges a little more code.
  sum = (sum < 0) ? sum - size/2 : sum   size/2;
  return (int) (sum / size);
}

*1 The width needed is the width of int plus the width of size_t. To truly handle very extreme averaging, takes additional code.

CodePudding user response:

To add to the comments you could make it more understandable by accumulating the results of division and reminders of division in 2 varaibles like this:

int CalculateAverage(const int array[], size_t size) {
    if (size == 0) return 0;
    int sum_of_divided = 0, sum_of_remainders = 0;
    for (int i = 0; i < size; i  ) {
        sum_of_divided  = array[i] / size;
        sum_of_remainders  = array[i] % size;
    }
    return sum_of_divided   sum_of_remainders / size;
}

This doesn't require floats and is thus not susceptible to floating point precision errors.

CodePudding user response:

Problem solved based on this comment from @abelenky: long total = 0.

CodePudding user response:

//Working example
#include <stdio.h>
#include <stddef.h>
#include <math.h>

void main() {
    
float CalculateAverage (int array[], int arr_size)
{
    int total=0;
    float average=0;
    if (arr_size == 0)
    {
        return 0;
    }
    for (int i=0; i<arr_size; i  )
    {
        total  = array[i];
    }
    printf("Size of array = %d", arr_size);
    printf("\nSum of array = %d", total);
    average = (float) total / arr_size;
    printf("\nActual average = %f", average);
    return average;
}

int numArray[] = {7, 8, 9, 11, 13}; 
int arr_size = sizeof(numArray)/sizeof(numArray[0]);
//You can manually pass the array size if you don't want to use any built-in function
float avg = CalculateAverage(numArray, arr_size);
if(avg>0)
    {
        float tempNum = avg*10;
        float reminder = fmodf(tempNum, 10);
        if(reminder >= 5)
        {
            avg  ;
        }
           printf("\nRounded off average = %d", (int)avg);
    }
    else{
        printf("Average = %lf", avg);
    }
}

  • Related