tina-core 0.0.2

Tina platform
Documentation
//! 数字
use bigdecimal::BigDecimal;
use num_bigint::BigInt;
use num_traits::{FromPrimitive, Pow};
use rand::{thread_rng, Rng};
use tracing::error;

/// 生成随机数
pub trait RandomNumber<T> {
    /// 生成范围在low~high之间的随机数
    fn random(low: T, high: T) -> T;
}

impl RandomNumber<i8> for i8 {
    fn random(low: i8, high: i8) -> i8 {
        thread_rng().gen_range(low..=high)
    }
}

impl RandomNumber<i16> for i16 {
    fn random(low: i16, high: i16) -> i16 {
        thread_rng().gen_range(low..=high)
    }
}

impl RandomNumber<i32> for i32 {
    fn random(low: i32, high: i32) -> i32 {
        thread_rng().gen_range(low..=high)
    }
}

impl RandomNumber<i64> for i64 {
    fn random(low: i64, high: i64) -> i64 {
        thread_rng().gen_range(low..=high)
    }
}

impl RandomNumber<u8> for u8 {
    fn random(low: u8, high: u8) -> u8 {
        thread_rng().gen_range(low..=high)
    }
}

impl RandomNumber<u16> for u16 {
    fn random(low: u16, high: u16) -> u16 {
        thread_rng().gen_range(low..=high)
    }
}

impl RandomNumber<u32> for u32 {
    fn random(low: u32, high: u32) -> u32 {
        thread_rng().gen_range(low..=high)
    }
}

impl RandomNumber<u64> for u64 {
    fn random(low: u64, high: u64) -> u64 {
        thread_rng().gen_range(low..=high)
    }
}

impl RandomNumber<f32> for f32 {
    fn random(low: f32, high: f32) -> f32 {
        thread_rng().gen_range(low..=high)
    }
}

impl RandomNumber<f64> for f64 {
    fn random(low: f64, high: f64) -> f64 {
        thread_rng().gen_range(low..=high)
    }
}

impl RandomNumber<isize> for isize {
    fn random(low: isize, high: isize) -> isize {
        thread_rng().gen_range(low..=high)
    }
}

impl RandomNumber<usize> for usize {
    fn random(low: usize, high: usize) -> usize {
        thread_rng().gen_range(low..=high)
    }
}

/// 精度数字
pub trait RoundNumber<Num> {
    /// 精确
    fn round_num(&self, round_digit: i16, half_up: bool) -> Num;
}

impl RoundNumber<f32> for f32 {
    fn round_num(&self, round_digit: i16, half_up: bool) -> f32 {
        match BigDecimal::from_f32(*self) {
            None => *self,
            Some(v) => match half_up {
                true => match v.round(round_digit as i64).to_string().parse::<f32>() {
                    Ok(v) => v,
                    Err(err) => {
                        error!("数字转换失败: {}, reason: {:?}", self, err);
                        *self
                    }
                },
                false => {
                    let multiplier: f64 = 10.0f64.pow(round_digit);
                    let num = ((*self as f64) * multiplier) as i64;
                    match BigDecimal::new(BigInt::from(num), round_digit as i64).to_string().parse::<f32>() {
                        Ok(v) => v,
                        Err(err) => {
                            error!("数字转换失败: {}, reason: {:?}", self, err);
                            *self
                        }
                    }
                }
            },
        }
    }
}

impl RoundNumber<f64> for f64 {
    fn round_num(&self, round_digit: i16, half_up: bool) -> f64 {
        match BigDecimal::from_f64(*self) {
            None => *self,
            Some(v) => match half_up {
                true => match v.round(round_digit as i64).to_string().parse::<f64>() {
                    Ok(v) => v,
                    Err(err) => {
                        error!("数字转换失败: {}, reason: {:?}", self, err);
                        *self
                    }
                },
                false => {
                    let multiplier: f64 = 10.0f64.pow(round_digit);
                    let num = ((*self) * multiplier) as i64;
                    match BigDecimal::new(BigInt::from(num), round_digit as i64).to_string().parse::<f64>() {
                        Ok(v) => v,
                        Err(err) => {
                            error!("数字转换失败: {}, reason: {:?}", self, err);
                            *self
                        }
                    }
                }
            },
        }
    }
}