foundry_common/
calc.rs

1//! Commonly used calculations.
2
3/// Returns the mean of the slice.
4#[inline]
5pub fn mean(values: &[u64]) -> u64 {
6    if values.is_empty() {
7        return 0;
8    }
9
10    (values.iter().map(|x| *x as u128).sum::<u128>() / values.len() as u128) as u64
11}
12
13/// Returns the median of a _sorted_ slice.
14#[inline]
15pub fn median_sorted(values: &[u64]) -> u64 {
16    if values.is_empty() {
17        return 0;
18    }
19
20    let len = values.len();
21    let mid = len / 2;
22    if len % 2 == 0 {
23        (values[mid - 1] + values[mid]) / 2
24    } else {
25        values[mid]
26    }
27}
28
29#[cfg(test)]
30mod tests {
31    use super::*;
32
33    #[test]
34    fn calc_mean_empty() {
35        let m = mean(&[]);
36        assert_eq!(m, 0);
37    }
38
39    #[test]
40    fn calc_mean() {
41        let m = mean(&[0, 1, 2, 3, 4, 5, 6]);
42        assert_eq!(m, 3);
43    }
44
45    #[test]
46    fn calc_mean_overflow() {
47        let m = mean(&[0, 1, 2, u32::MAX as u64, 3, u16::MAX as u64, u64::MAX, 6]);
48        assert_eq!(m, 2305843009750573057);
49    }
50
51    #[test]
52    fn calc_median_empty() {
53        let m = median_sorted(&[]);
54        assert_eq!(m, 0);
55    }
56
57    #[test]
58    fn calc_median() {
59        let mut values = vec![29, 30, 31, 40, 59, 61, 71];
60        values.sort();
61        let m = median_sorted(&values);
62        assert_eq!(m, 40);
63    }
64
65    #[test]
66    fn calc_median_even() {
67        let mut values = vec![80, 90, 30, 40, 50, 60, 10, 20];
68        values.sort();
69        let m = median_sorted(&values);
70        assert_eq!(m, 45);
71    }
72}