Functional Weave
Code in Rust

stats.mean-median@1.0.0

README.md

1,577 bytes · view raw

# stats.mean-median

Mean, median and mode of a list of integers, in one pass over one sorted copy.

The mean and median are returned as exact fractions in lowest terms (`7/2`, not
`3.5` and certainly not `3`, which is what integer division gives). Each also
comes as a float, `meanValue` and `medianValue`, computed by one IEEE-754
division of the exact numerator by the exact denominator. That single division
is correctly rounded in every language, so TypeScript, Python and Rust return
the same double to the last bit; there is no accumulated float error to
disagree about, because the sum is an exact integer.

Inputs are integers on purpose. Averages of money, weights or counts should be
taken in their smallest unit (pence, grams), where they are exact; divide at the
edge. Every value must be a safe integer (magnitude at most 2^53 - 1, the range
all three languages share), and so must the sum. A list whose sum leaves that
range is an error, not a silently rounded answer. The same goes for the median
of an even-length list when the two middle values add up past it and do not
halve evenly.

The median sorts numerically. A naive JavaScript `values.sort()` sorts as
strings and puts 10 before 9; the vectors pin that down. The input list is
never mutated.

`modes` lists every value that shares the highest frequency, ascending. When no
value repeats, `modeFrequency` is 1 and every value is listed: whether that
counts as "no mode" is the caller's call, and `modeFrequency` makes it a
one-line test.

An empty list is an error: there is no honest mean of nothing.