fastnum2 0.3.6

fork of Fast decimal numbers library
Documentation
use crate::{int::UInt, utils::err_msg};

pub type Digit = u64;
pub type DoubleDigit = u128;
pub type ExpType = u32;

pub type Digits<const N: usize> = [Digit; N];

pub const POWER: u32 = 19;
pub const BITS: ExpType = Digit::BITS;
pub const BITS_MINUS_1: ExpType = BITS - 1;
pub const BIT_SHIFT: ExpType = BITS.trailing_zeros();

#[repr(transparent)]
pub struct PowersOf10<const N: usize>([[UInt<N>; POWER as usize + 1]; N]);

impl<const N: usize> PowersOf10<N> {
    #[inline]
    const fn new() -> Self {
        debug_assert!(N > 0);
        debug_assert!((UInt::<N>::MAX.ilog10()) < (POWER + 1) * (N as u32));

        let mut res = [[UInt::ZERO; POWER as usize + 1]; N];
        res[0][0] = UInt::ONE;

        let mut v;
        let mut j = 0;
        let mut i = 1;
        v = UInt::ONE;
        while v.le(&UInt::<N>::MAX.div(UInt::TEN)) {
            v = v.strict_mul(UInt::TEN);
            res[j][i] = v;
            i += 1;

            if i == POWER as usize + 1 {
                i = 0;
                j += 1;
            }
        }

        Self(res)
    }

    #[inline(always)]
    pub const fn lookup(&self, power: u32) -> UInt<N> {
        let j = (power / (POWER + 1)) as usize;

        if j >= N {
            panic!(err_msg!("power is too large"));
        }

        let i = (power % (POWER + 1)) as usize;
        self.0[j][i]
    }
}

pub struct Intrinsics<const N: usize>;

impl<const N: usize> Intrinsics<N> {
    pub const MAX_POWER_OF_TEN: u32 = (POWER + 1) * (N as u32);

    #[allow(long_running_const_eval)]
    pub const POWERS_OF_TEN: PowersOf10<N> = PowersOf10::new();
}