pub(super) fn count_to_f64(n: usize) -> f64 {
let wide = u64::try_from(n).unwrap_or(u64::MAX);
let hi = u32::try_from(wide >> 32).unwrap_or(0);
let lo = u32::try_from(wide & 0xFFFF_FFFF).unwrap_or(0);
f64::from(hi).mul_add(4_294_967_296.0, f64::from(lo))
}
pub(super) fn sample_variance(values: &[f64]) -> f64 {
let n = count_to_f64(values.len());
if n < 2.0 {
return 0.0;
}
let mean = values.iter().sum::<f64>() / n;
let ss: f64 = values
.iter()
.map(|&v| {
let d = v - mean;
d * d
})
.sum();
ss / (n - 1.0)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn count_widens_exactly() {
assert!((count_to_f64(2048) - 2048.0).abs() < 1e-12, "widening");
}
#[test]
fn variance_matches_hand_value() {
let v = sample_variance(&[2.0, 4.0, 6.0]);
assert!((v - 4.0).abs() < 1e-12, "variance was {v}");
}
#[test]
fn variance_of_singleton_is_zero() {
assert!(sample_variance(&[3.0]).abs() < 1e-12, "singleton variance");
}
}