Skip to content

Commit ddd3934

Browse files
committed
cbits: avoid div-by-zero, and thus NaN
A newly-created a `Distribution` has a flaw: its `mean` value is set to `NaN` by default upon the first reading, providing no samples have been previously added. Why? Because a newly created `Distribution` named `d` has a field `d->count = 0`, which is used as a divisor for a float value. And the numerator ends up zero too, as well. IEEE-754 defines the value of 0.0/0.0 as NaN, and so on the first reading of a `Distribution` with no samples, `NaN` is returned for the `mean`. This is problematic for a use case of mine: I want to use `ekg-statsd` to export `Distribution` values a metric logging system. However, without this patch, the `mean` value is reported as `NaN` (thanks to its `Show` instance), which causes the logging system to reject the metric because it strictly expects floating-point values. I wouldn't be surprised if other systems rejected `NaN` in such a case when they try to scrape metrics. And it's not something clients of `ekg-core` should really check for. In this case, the fix is a little simple: we just check for `count == 0` and return a mean of `0.0` if that's the case. Signed-off-by: Austin Seipp <aseipp@pobox.com>
1 parent 813aa42 commit ddd3934

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

cbits/distrib.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ void hs_distrib_combine(struct distrib* b, struct distrib* a) {
3535
const StgDouble sum_sq_delta = (a->sum_sq_delta + b->sum_sq_delta +
3636
delta * delta * (a->count * b->count) / count);
3737
a->count = count;
38-
a->mean = mean;
38+
a->mean = (count == 0) ? 0.0 : mean; // divide-by-zero gives NaN
3939
a->sum_sq_delta = sum_sq_delta;
4040
a->sum = a->sum + b->sum;
4141
a->min = b->min;

0 commit comments

Comments
 (0)