Shared Rust kernels
ported/percentrank_common
All modules · quoted at commit 9e1884369a67 of DnaCalc/DnaCalc. Comments are the source's own.
percentrank · 36 lines · calc-func/src/ported/percentrank_common.rs on GitHubpub fn percentrank(
values: &mut [f64],
x: f64,
significance: i64,
mode: PercentRankMode,
) -> Result<f64, WorksheetErrorCode> {
if values.is_empty() {
return Err(WorksheetErrorCode::NA);
}
if significance <= 0 {
return Err(WorksheetErrorCode::Num);
}
values.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
let first = values[0];
let last = values[values.len() - 1];
if x < first || x > last {
return Err(WorksheetErrorCode::NA);
}
let base =
match values.binary_search_by(|v| v.partial_cmp(&x).unwrap_or(std::cmp::Ordering::Equal)) {
Ok(idx) => exact_rank(idx, values.len(), mode),
Err(upper) => {
if upper == 0 || upper >= values.len() {
return Err(WorksheetErrorCode::NA);
}
let lower = upper - 1;
let lower_x = values[lower];
let upper_x = values[upper];
let lower_rank = exact_rank(lower, values.len(), mode);
let upper_rank = exact_rank(upper, values.len(), mode);
lower_rank + (x - lower_x) * (upper_rank - lower_rank) / (upper_x - lower_x)
}
};
Ok(truncate_to_decimal_places(base, significance))
}
Used by 3 functions.
exact_rank · 6 lines · calc-func/src/ported/percentrank_common.rs on GitHubfn exact_rank(index: usize, len: usize, mode: PercentRankMode) -> f64 {
match mode {
PercentRankMode::Inclusive => index as f64 / (len as f64 - 1.0),
PercentRankMode::Exclusive => (index as f64 + 1.0) / (len as f64 + 1.0),
}
}
Used by 3 functions.
truncate_to_decimal_places · 9 lines · calc-func/src/ported/percentrank_common.rs on GitHub/// The rank truncated to `places` decimal places, trunc(value*10^places)/10^places: Excel's
/// `significance` counts decimal places, not significant digits (dc-j9k: 301 of 301
/// PERCENTRANK, PERCENTRANK.INC and PERCENTRANK.EXC readings in the catalogue oracle's sheet
/// dcj9k_statistics; PERCENTRANK.INC(...,5.93) is 0.037, where three significant digits
/// gave 0.0373).
fn truncate_to_decimal_places(value: f64, places: i64) -> f64 {
let scale = 10f64.powi(places.min(308) as i32);
(value * scale).trunc() / scale
}
Used by 3 functions.