This question is a follow up of: Calculate min, max, mean and median out of array
I took all the suggestions an reworked the code. Like the description of the excercise suggests i only use one function for all the computations. Also with the sorting the max and median values can now be calculated easier.
I wonder if its good to return the Macro types INT_MIN
INT_MAX
and NAN
for indicating no valid result?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <limits.h>
#include <math.h>
struct Summary_data {
long long smallest;
long long largest;
double median;
double mean;
};
static inline int cmp(void const *lhs, void const *rhs) {
const int *left = (const int *)lhs;
const int *right = (const int *)rhs;
return (*left > *right) - (*left < *right);
}
int* intdup(const int * source, const size_t len)
{
assert(source);
int * p = malloc(len * sizeof(*source));
if (p == NULL)
exit(1);
memcpy(p, source, len * sizeof(*source));
return p;
}
struct Summary_data calculate_values(const int* array, const size_t len)
{
assert(array);
struct Summary_data summary_data = { 0 };
int* calc_array = intdup(array, len);
size_t i;
if (len <= 0) { // dont bother to calc if invalid len
free(calc_array);
calc_array = NULL;
summary_data.smallest = INT_MAX;
summary_data.largest = INT_MIN;
summary_data.mean = NAN;
summary_data.median = NAN;
return summary_data;
}
qsort(calc_array, len, sizeof *array, cmp);
summary_data.smallest = calc_array[0];
summary_data.largest = calc_array[len - 1];
for (i = 0; i < len; ++i) {
summary_data.mean += calc_array[i];
}
summary_data.mean /= len;
if (len % 2 == 0) { // is even == return the arithmetic middle of the two middle values
summary_data.median = (calc_array[(len - 1) / 2] + calc_array[len / 2]) / 2.0;
}
else { // is odd == retunr the middle
summary_data.median = calc_array[len / 2];
}
free(calc_array);
calc_array = NULL;
return summary_data;
}
void print_result(const struct Summary_data* summary_data)
{
assert(summary_data);
printf("smallest: %i\n", summary_data->smallest);
printf("largest: %i\n", summary_data->largest);
printf("median: %g\n", summary_data->median);
printf("mean: %g\n\n", summary_data->mean);
}
int main()
{
int test_array[] = { 1,7,3,4,5,6,7,8,9 }; // 9 elements
// int test_array[] = { 1,7,3,4,5,6,7,8 }; // 8 elements
int len = sizeof(test_array) / sizeof(test_array[0]);
//len = 0; // test when len is invalid
struct Summary_data summary_data = calculate_values(test_array, len);
print_result(&summary_data);
getchar();
return 0;
}