use bitrep::SumF64;
fn lre(computed: f64, certified: f64) -> f64 {
if computed == certified {
return 16.0; }
-((computed - certified).abs() / certified.abs()).log10()
}
fn mean(values: impl Iterator<Item = f64>, n: u64) -> f64 {
let acc: SumF64 = values.collect();
assert_eq!(acc.count(), n);
acc.value() / n as f64
}
fn numacc_pattern(base: &str, low: &str, high: &str) -> Vec<f64> {
let mut v = vec![base.parse::<f64>().unwrap()];
for _ in 0..500 {
v.push(low.parse().unwrap());
v.push(high.parse().unwrap());
}
v
}
#[test]
fn numacc1() {
let m = mean([10000001.0, 10000003.0, 10000002.0].into_iter(), 3);
assert_eq!(
m, 10000002.0,
"NumAcc1 certified mean is exact-representable; no excuse"
);
}
#[test]
fn numacc2() {
let data = numacc_pattern("1.2", "1.1", "1.3");
let m = mean(data.into_iter(), 1001);
let score = lre(m, 1.2);
assert!(
score >= 14.5,
"NumAcc2 LRE {score:.2} < 14.5 (mean {m:.17})"
);
}
#[test]
fn numacc3() {
let data = numacc_pattern("1000000.2", "1000000.1", "1000000.3");
let m = mean(data.into_iter(), 1001);
let score = lre(m, 1000000.2);
assert!(
score >= 14.5,
"NumAcc3 LRE {score:.2} < 14.5 (mean {m:.17})"
);
}
#[test]
fn numacc4() {
let data = numacc_pattern("10000000.2", "10000000.1", "10000000.3");
let m = mean(data.into_iter(), 1001);
let score = lre(m, 10000000.2);
assert!(
score >= 14.5,
"NumAcc4 LRE {score:.2} < 14.5 (mean {m:.17})"
);
}
#[test]
fn numacc4_sharded_bitwise() {
let data = numacc_pattern("10000000.2", "10000000.1", "10000000.3");
let whole: SumF64 = data.iter().copied().collect();
let mut merged = SumF64::new();
for chunk in data.chunks(97) {
let shard: SumF64 = chunk.iter().copied().collect();
merged.merge(&shard);
}
assert_eq!(whole.to_bytes(), merged.to_bytes());
let revived = SumF64::from_bytes(&merged.to_bytes()).unwrap();
assert_eq!(revived.value().to_bits(), whole.value().to_bits());
}