/**
* @brief Comparison function for qsort to sort double arrays
*/
static int double_cmp(const void *a, const void *b) {
double val_a = *(const double *)a;
double val_b = *(const double *)b;
if (val_a < val_b) return -1;
if (val_a > val_b) return 1;
return 0;
}
/**
* @brief Filters NAN/INF, removes the maximum and minimum values, and calculates the average
* @param input Input array
* @param input_len Length of the input array
* @param avg_result Output: calculated average value
* @return 0: success, -1: failure (e.g., insufficient elements after filtering, invalid parameters)
*/
int calc_avg_filtered(double *input, int input_len, double *avg_result) {
// 1. Check the validity of input parameters
if (input == NULL || avg_result == NULL || input_len <= 0) {
fprintf(stderr, “Invalid input parameters\n”);
errno = EINVAL;
return -1;
}
// 2. Step one: Filter NAN and INF, store in a temporary array
double *filtered = (double *)malloc(input_len * sizeof(double));
if (filtered == NULL) {
fprintf(stderr, “Malloc failed: %m\n”);
errno = ENOMEM;
return -1;
}
int filtered_len = 0;
for (int i = 0; i < input_len; i++) {
// Filter NAN (isnan) and INF (isinf)
if (!isnan(input[i]) && !isinf(input[i])) {
filtered[filtered_len++] = input[i];
}
}
// 3. Boundary condition: insufficient elements after filtering (cannot remove max + min)
if (filtered_len < 3) {
fprintf(stderr, “Filtered elements count(%d) < 3, can’t remove max/min\n”, filtered_len);
free(filtered);
errno = EINVAL;
return -1;
}
// 4. Sort the filtered array (to easily get max/min values)
qsort(filtered, filtered_len, sizeof(double), double_cmp);
// 5. Remove the first (minimum) and last (maximum) values, calculate the sum of the remaining elements
double sum = 0.0;
int valid_len = filtered_len – 2; // Number of elements after removing max + min
for (int i = 1; i < filtered_len – 1; i++) {
sum += filtered[i];
}
// 6. Calculate the average
*avg_result = sum / valid_len;
// 7. Free resources
free(filtered);
return 0;
}
// Test main function
int main() {
// Test array (contains NAN, INF, normal values)
double test_data[] = {9.9, 9.1199, NAN, INFINITY, -INFINITY, 8.5, 10.2, 7.8, 9.0};
int data_len = sizeof(test_data) / sizeof(test_data[0]);
double avg;
// Call the calculation function
int ret = calc_avg_filtered(test_data, data_len, &avg);
if (ret == 0) {
printf(“Average after filtering NAN/INF and removing max/min: %.4f\n”, avg);
} else {
printf(“Calculation failed, error code: %d\n”, errno);
}
return 0;
}
// Compile with LINUX GCC as follows
gcc -o avg_filter avg_filter.c -lm./avg_filter