#[inline]
pub(crate) fn kahan_add(sum: &mut f64, comp: &mut f64, x: f64) {
let y = x - *comp;
let t = *sum + y;
*comp = (t - *sum) - y;
*sum = t;
}
#[cfg(feature = "python")]
pub(crate) fn normal_quantile(p: f64) -> f64 {
let t = (-2.0 * (1.0 - p).ln()).sqrt();
let c = [2.515_517, 0.802_853, 0.010_328];
let d = [1.432_788, 0.189_269, 0.001_308];
t - (c[0] + c[1] * t + c[2] * t * t) / (1.0 + d[0] * t + d[1] * t * t + d[2] * t * t * t)
}
#[cfg(all(test, feature = "python"))]
mod tests {
use super::*;
#[test]
fn normal_quantile_matches_known_z_scores() {
let cases = [(0.90, 1.644854), (0.95, 1.959964), (0.99, 2.575829)];
for (ci_level, expected_z) in cases {
let z = normal_quantile((1.0 + ci_level) / 2.0);
assert!(
(z - expected_z).abs() < 0.01,
"normal_quantile for {ci_level} CI: expected z≈{expected_z}, got {z}"
);
}
}
}