calculated_number grouping_flush_median(RRDR *r, RRDR_VALUE_FLAGS *rrdr_value_options_ptr) { struct grouping_median *g = (struct grouping_median *)r->grouping_data; calculated_number value; if(unlikely(!g->next_pos)) { value = 0.0; *rrdr_value_options_ptr |= RRDR_VALUE_EMPTY; } else { if(g->next_pos > 1) { sort_series(g->series, g->next_pos); value = (calculated_number)median_on_sorted_series(g->series, g->next_pos); } else value = (calculated_number)g->series[0]; if(!isnormal(value)) { value = 0.0; *rrdr_value_options_ptr |= RRDR_VALUE_EMPTY; } //log_series_to_stderr(g->series, g->next_pos, value, "median"); } g->next_pos = 0; return value; }
long double median(const long double *series, size_t entries) { if(unlikely(entries == 0)) return NAN; if(unlikely(entries == 1)) return series[0]; if(unlikely(entries == 2)) return (series[0] + series[1]) / 2; long double *copy = copy_series(series, entries); sort_series(copy, entries); long double avg = median_on_sorted_series(copy, entries); freez(copy); return avg; }