diff --git a/src/ordinal.rs b/src/ordinal.rs index cb4caafc5b..7f330e3b85 100644 --- a/src/ordinal.rs +++ b/src/ordinal.rs @@ -158,11 +158,19 @@ impl Ordinal { let percentile = percentile[..percentile.len() - 1].parse::()?; - let position = percentile / 100.0; + if percentile < 0.0 { + bail!("Invalid percentile: {}", percentile); + } + + let last = Ordinal::LAST.n() as f64; - let n = position * Ordinal::LAST.n() as f64; + let n = (percentile / 100.0 * last).round() as u64; - Ok(Ordinal(n.round() as u64)) + if n > Ordinal::LAST.n() { + bail!("Invalid percentile: {}", percentile); + } + + Ok(Ordinal(n as u64)) } } @@ -520,6 +528,12 @@ mod tests { assert_eq!(Ordinal::LAST.percentile(), "100%"); } + #[test] + fn from_percentile() { + "-1%".parse::().unwrap_err(); + "101%".parse::().unwrap_err(); + } + #[test] fn percentile_round_trip() { fn case(n: u64) {