mod add; mod div; mod from; mod mul; mod ord; mod sub; use std::fmt::{Display, Formatter}; #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum Sign { Positif, Negatif, } #[derive(Clone, Debug, Eq, PartialEq, Hash)] pub struct Number { pub digits: Vec<isize>, pub sign: Sign, } impl Number { pub fn get_digit(n: isize, pos: usize) -> isize { let modulo = 10isize.pow(pos as u32 + 1); let divisor = modulo / 10; (n % modulo) / divisor } pub const fn byte_to_digit(b: u8) -> isize { // wrapping_sub('0' as u32) same as - 48 but less magical (b as isize).wrapping_sub('0' as isize) } pub fn pow(self, n: u32) -> Self { let mut result = self.clone(); if ((self.digits.len() * 8) as u32) < isize::BITS { let number = isize::try_from(self).unwrap(); for _i in 1..n { result = result * number; } result } else { let number = self.clone(); for _i in 1..n { result *= number.clone(); } result } } pub fn fact(self) -> Self { let mut fact = Number::from(1); if ((self.digits.len() * 8) as u32) < isize::BITS { let max = isize::try_from(self).unwrap(); for n in 1..=max { fact = fact * n; } fact } else { panic!("starting number too big") } } pub fn fib(n: u64) -> Self { let mut last_two = (Self::from(1), Self::from(1)); let mut iteration = 1; while iteration < n { last_two = (last_two.1.clone(), last_two.0 + last_two.1); iteration += 1; } last_two.0 } } impl Display for Number { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { let number_string = self .digits .iter() .rev() .map(|&digit| digit.to_string()) .collect::<Vec<String>>() .join(""); match self.sign { Sign::Positif => write!(f, "{number_string}"), Sign::Negatif => write!(f, "-{number_string}"), } } } #[cfg(test)] mod number_tests { use crate::number::Number; #[test] fn test_get_digit() { let num = 12345; let digit_1 = Number::get_digit(num, 0); let digit_2 = Number::get_digit(num, 1); let digit_3 = Number::get_digit(num, 2); let digit_4 = Number::get_digit(num, 3); let digit_5 = Number::get_digit(num, 4); assert_eq!(digit_1, 5); assert_eq!(digit_2, 4); assert_eq!(digit_3, 3); assert_eq!(digit_4, 2); assert_eq!(digit_5, 1); } }