Shared Rust kernels

ported/base_fn

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

int_to_base · 13 lines · calc-func/src/ported/base_fn.rs on GitHub
fn int_to_base(mut value: i64, radix: i64) -> String {
    const DIGITS: &[u8] = b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    if value == 0 {
        return "0".to_string();
    }
    let mut out = Vec::new();
    while value > 0 {
        let digit = (value % radix) as usize;
        out.push(DIGITS[digit] as char);
        value /= radix;
    }
    out.into_iter().rev().collect()
}

Used by 10 functions.

base_kernel · 32 lines · calc-func/src/ported/base_fn.rs on GitHub
pub fn base_kernel(
    number: f64,
    radix: f64,
    min_length: Option<f64>,
) -> Result<ExcelText, WorksheetErrorCode> {
    // Value2 captures on Excel 20430/CV2: sign and 2^53 admission precede
    // truncation, while the optional length is truncated within 0..255.
    if !number.is_finite() || !(0.0..9_007_199_254_740_992.0).contains(&number)
        || !radix.is_finite()
        || min_length.is_some_and(|n| !n.is_finite() || n < 0.0)
    {
        return Err(WorksheetErrorCode::Num);
    }
    let number = number.trunc();
    let radix = radix.trunc();
    let min_length = min_length.unwrap_or(1.0).trunc();
    if !(2.0..=36.0).contains(&radix) || min_length > 255.0 {
        return Err(WorksheetErrorCode::Num);
    }
    // An explicit zero length differs from omitting the optional argument.
    let mut out = if number == 0.0 && min_length == 0.0 {
        String::new()
    } else {
        int_to_base(number as i64, radix as i64)
    };
    while out.len() < min_length as usize {
        out.insert(0, '0');
    }
    Ok(ExcelText::from_utf16_code_units(
        out.encode_utf16().collect(),
    ))
}

Used by 10 functions.