reference_interval/
mean.rs

1use num_traits::{Float, NumCast};
2
3// Calculate the mean of two numbers, with special handling for overflow cases.
4#[allow(dead_code)]
5pub fn mean<F>(a: F, b: F) -> F 
6where
7    F: Float + NumCast,
8{
9    if (b > F::zero()) && (a > (F::max_value() - b)) {
10      // Will overflow, so use difference method.
11      // Both a and b > 0.
12      // We want difference also > 0 so rounding works correctly.
13      if a >= b {
14        b + (a - b) / F::from(2.0).unwrap()
15      } else {
16        a + (b - a) / F::from(2.0).unwrap()
17      }
18    } else {
19        if (b < F::zero()) && (a < (F::min_value() - b)) {
20            // Will overflow, so use difference method.
21            // Both a and b < 0.
22            // We want difference also < 0 so rounding works correctly.
23            if a <= b {
24                b + (a - b) / F::from(2.0).unwrap()
25            } else {
26                a + (b - a) / F::from(2.0).unwrap()
27            }
28        } else {
29            // Will not overflow.
30            (a + b) / F::from(2.0).unwrap()
31        }
32    }
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    #[test]
40    fn test() {
41        let x = mean(11.0, 97.0);
42        assert_eq!(x as i32, 54);
43    }
44
45}