Shared Rust kernels

ported/ceiling_floor_family

All modules · quoted at commit 9e1884369a67 of DnaCalc/DnaCalc. Comments are the source's own.

excel_quotient · 12 lines · calc-func/src/ported/ceiling_floor_family.rs on GitHub
/// The quotient number/significance as the CEILING and FLOOR family counts multiples from it:
/// rounded to 15 significant digits first, so a quotient within that rounding of an integer is
/// that integer (dc-j9k: 736 of 736 CEILING, FLOOR, .MATH and .PRECISE readings in the catalogue
/// oracle's sheet dcj9k_math; CEILING(1*(1+2^-48),1) is 1 and CEILING(1*(1+2^-47),1) is 2,
/// FLOOR(1*(1-2^-51),1) is 1 and FLOOR(1*(1-2^-50),1) is 0).
pub(crate) fn excel_quotient(number: f64, significance: f64) -> f64 {
    let quotient = number / significance;
    if !quotient.is_finite() || quotient == 0.0 {
        return quotient;
    }
    format!("{quotient:.14e}").parse().unwrap_or(quotient)
}

Used by 8 functions.

normalize_zero · 3 lines · calc-func/src/ported/ceiling_floor_family.rs on GitHub
fn normalize_zero(x: f64) -> f64 {
    if x == 0.0 { 0.0 } else { x }
}

Used by 5 functions.

ceiling_math_kernel · 18 lines · calc-func/src/ported/ceiling_floor_family.rs on GitHub
pub fn ceiling_math_kernel(
    number: f64,
    significance: f64,
    mode: f64,
) -> Result<f64, WorksheetErrorCode> {
    let significance = significance.abs();
    if significance == 0.0 {
        return Ok(0.0);
    }
    let result = if number >= 0.0 {
        significance * excel_quotient(number, significance).ceil()
    } else if mode != 0.0 {
        -significance * excel_quotient(-number, significance).ceil()
    } else {
        -significance * excel_quotient(-number, significance).floor()
    };
    Ok(normalize_zero(result))
}

Used by 3 functions.

floor_math_kernel · 18 lines · calc-func/src/ported/ceiling_floor_family.rs on GitHub
pub fn floor_math_kernel(
    number: f64,
    significance: f64,
    mode: f64,
) -> Result<f64, WorksheetErrorCode> {
    let significance = significance.abs();
    if significance == 0.0 {
        return Ok(0.0);
    }
    let result = if number >= 0.0 {
        significance * excel_quotient(number, significance).floor()
    } else if mode != 0.0 {
        -significance * excel_quotient(-number, significance).floor()
    } else {
        -significance * excel_quotient(-number, significance).ceil()
    };
    Ok(normalize_zero(result))
}

Used by 2 functions.