1use std::cmp::max;
4
5pub fn abridge<const DIGITS: usize>(value: f64, abridge: Abridging, rounding: Rounding) -> f64 {
7 let power = 10.0f64.powi(trailing_digits::<DIGITS>(value, abridge) as _);
8 round(value * power, rounding) / power
9}
10
11fn round(value: f64, rounding: Rounding) -> f64 {
12 match rounding {
13 Rounding::Floor => value.floor(),
15 Rounding::Ceil => value.ceil(),
17 Rounding::Round => value.round(),
19 }
20}
21
22fn trailing_digits<const DIGITS: usize>(value: f64, abridge: Abridging) -> usize {
23 let leading_digits = value.abs().log10().ceil();
24 match abridge {
25 Abridging::Significant => max(0, DIGITS as isize - leading_digits as isize) as _,
27 Abridging::Mantissa => DIGITS,
28 Abridging::Total => DIGITS.saturating_sub(leading_digits as usize),
30 }
31}
32
33#[derive(Clone, Copy, Debug, Eq, PartialEq)]
35pub enum Abridging {
36 Significant,
38 Mantissa,
40 Total,
42}
43
44#[derive(Clone, Copy, Debug, PartialEq)]
46pub enum Rounding {
47 Floor,
49 Ceil,
51 Round,
53}
54
55pub mod prelude {
56 pub use crate::{
57 abridge,
58 Abridging::{Mantissa, Significant, Total},
59 Rounding::{Ceil, Floor, Round},
60 };
61}