nexus-decimal 1.2.2

Fixed-point decimal arithmetic with compile-time precision
Documentation
//! Compile-time power-of-10 lookup table.
//!
//! Covers `10^0` through `10^38` (full `i128` range).

/// Powers of 10 from `10^0` to `10^38`.
const POW10: [u128; 39] = [
    1,
    10,
    100,
    1_000,
    10_000,
    100_000,
    1_000_000,
    10_000_000,
    100_000_000, // 10^8
    1_000_000_000,
    10_000_000_000,
    100_000_000_000,
    1_000_000_000_000, // 10^12
    10_000_000_000_000,
    100_000_000_000_000,
    1_000_000_000_000_000,
    10_000_000_000_000_000,
    100_000_000_000_000_000,
    1_000_000_000_000_000_000, // 10^18
    10_000_000_000_000_000_000,
    100_000_000_000_000_000_000,
    1_000_000_000_000_000_000_000,
    10_000_000_000_000_000_000_000,
    100_000_000_000_000_000_000_000,
    1_000_000_000_000_000_000_000_000,
    10_000_000_000_000_000_000_000_000,
    100_000_000_000_000_000_000_000_000,
    1_000_000_000_000_000_000_000_000_000,
    10_000_000_000_000_000_000_000_000_000,
    100_000_000_000_000_000_000_000_000_000,
    1_000_000_000_000_000_000_000_000_000_000,
    10_000_000_000_000_000_000_000_000_000_000,
    100_000_000_000_000_000_000_000_000_000_000,
    1_000_000_000_000_000_000_000_000_000_000_000,
    10_000_000_000_000_000_000_000_000_000_000_000,
    100_000_000_000_000_000_000_000_000_000_000_000,
    1_000_000_000_000_000_000_000_000_000_000_000_000,
    10_000_000_000_000_000_000_000_000_000_000_000_000,
    100_000_000_000_000_000_000_000_000_000_000_000_000, // 10^38
];

#[inline(always)]
pub(crate) const fn pow10_i32(exp: u8) -> i32 {
    debug_assert!(exp <= 9, "10^exp overflows i32");
    POW10[exp as usize] as i32
}

#[inline(always)]
pub(crate) const fn pow10_i64(exp: u8) -> i64 {
    debug_assert!(exp <= 18, "10^exp overflows i64");
    POW10[exp as usize] as i64
}

#[inline(always)]
pub(crate) const fn pow10_i128(exp: u8) -> i128 {
    debug_assert!(exp <= 38, "10^exp overflows i128");
    POW10[exp as usize] as i128
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn table_correctness() {
        let mut expected: u128 = 1;
        for (i, &entry) in POW10.iter().enumerate() {
            assert_eq!(entry, expected, "POW10[{i}] mismatch");
            if i < 38 {
                expected *= 10;
            }
        }
    }

    #[test]
    fn i32_boundaries() {
        assert_eq!(pow10_i32(0), 1);
        assert_eq!(pow10_i32(9), 1_000_000_000);
        // 10^9 = 1,000,000,000 fits in i32 (max 2,147,483,647)
    }

    #[test]
    fn i64_boundaries() {
        assert_eq!(pow10_i64(0), 1);
        assert_eq!(pow10_i64(18), 1_000_000_000_000_000_000);
    }

    #[test]
    fn i128_boundaries() {
        assert_eq!(pow10_i128(0), 1);
        assert_eq!(
            pow10_i128(38),
            100_000_000_000_000_000_000_000_000_000_000_000_000
        );
    }
}