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.is_multiple_of(2) { (values[mid - 1] + values[mid]) / 2 } else { values[mid] }
23}
24
25#[cfg(test)]
26mod tests {
27    use super::*;
28
29    #[test]
30    fn calc_mean_empty() {
31        let m = mean(&[]);
32        assert_eq!(m, 0);
33    }
34
35    #[test]
36    fn calc_mean() {
37        let m = mean(&[0, 1, 2, 3, 4, 5, 6]);
38        assert_eq!(m, 3);
39    }
40
41    #[test]
42    fn calc_mean_overflow() {
43        let m = mean(&[0, 1, 2, u32::MAX as u64, 3, u16::MAX as u64, u64::MAX, 6]);
44        assert_eq!(m, 2305843009750573057);
45    }
46
47    #[test]
48    fn calc_median_empty() {
49        let m = median_sorted(&[]);
50        assert_eq!(m, 0);
51    }
52
53    #[test]
54    fn calc_median() {
55        let mut values = vec![29, 30, 31, 40, 59, 61, 71];
56        values.sort();
57        let m = median_sorted(&values);
58        assert_eq!(m, 40);
59    }
60
61    #[test]
62    fn calc_median_even() {
63        let mut values = vec![80, 90, 30, 40, 50, 60, 10, 20];
64        values.sort();
65        let m = median_sorted(&values);
66        assert_eq!(m, 45);
67    }
68}