This commit is contained in:
KillerBossOriginal 2025-01-01 17:53:50 +01:00
parent ff2b8d5712
commit 4c2d0147ed
2 changed files with 156 additions and 6 deletions

154
src/big_numbers.rs Normal file
View file

@ -0,0 +1,154 @@
#[derive(Debug, Clone)]
pub struct BigDecimal {
integer_part: Vec<u8>,
fractional_part: Vec<u8>,
}
impl BigDecimal {
pub fn new(value: f64, precision: usize) -> Self {
let integer_part = (value.trunc() as u64)
.to_string()
.chars()
.map(|c| c.to_digit(10).unwrap() as u8)
.collect::<Vec<u8>>();
let mut fractional_part = Vec::new();
let mut fractional_value = value.fract();
for _ in 0..precision {
fractional_value *= 10.0;
let digit = fractional_value.trunc() as u8;
fractional_part.push(digit);
fractional_value -= fractional_value.trunc();
}
BigDecimal {
integer_part,
fractional_part,
}
}
pub fn from_str(s: &str, precision: usize) -> Result<Self, String> {
let mut parts = s.split('.');
let integer_part_str = parts.next().unwrap_or("");
let fractional_part_str = parts.next().unwrap_or("");
let integer_part = integer_part_str
.chars()
.map(|c| c.to_digit(10).ok_or("Non è un numero valido"))
.collect::<Result<Vec<u8>, &str>>()?;
let mut fractional_part = Vec::new();
for (i, c) in fractional_part_str.chars().enumerate() {
if i >= precision {
break;
}
let digit = c.to_digit(10).ok_or("Non è un numero valido")?;
fractional_part.push(digit as u8);
}
Ok(BigDecimal {
integer_part,
fractional_part,
})
}
pub fn to_string(&self) -> String {
let integer_str: String = self
.integer_part
.iter()
.map(|&d| (b'0' + d) as char)
.collect();
let fractional_str: String = self
.fractional_part
.iter()
.map(|&d| (b'0' + d) as char)
.collect();
if !self.fractional_part.is_empty() {
format!("{}.{}", integer_str, fractional_str)
} else {
integer_str
}
}
pub fn add(&self, other: &BigDecimal) -> BigDecimal {
let mut result_integer = Vec::new();
let mut result_fractional = Vec::new();
let mut carry = 0;
let max_fractional_len = self.fractional_part.len().max(other.fractional_part.len());
let mut self_frac = self.fractional_part.clone();
let mut other_frac = other.fractional_part.clone();
while self_frac.len() < max_fractional_len {
self_frac.push(0);
}
while other_frac.len() < max_fractional_len {
other_frac.push(0);
}
for i in (0..max_fractional_len).rev() {
let sum = self_frac[i] + other_frac[i] + carry;
result_fractional.push(sum % 10);
carry = sum / 10;
}
result_fractional.reverse();
let max_integer_len = self.integer_part.len().max(other.integer_part.len());
let mut self_int = self.integer_part.clone();
let mut other_int = other.integer_part.clone();
while self_int.len() < max_integer_len {
self_int.insert(0, 0);
}
while other_int.len() < max_integer_len {
other_int.insert(0, 0);
}
for i in (0..max_integer_len).rev() {
let sum = self_int[i] + other_int[i] + carry;
result_integer.push(sum % 10);
carry = sum / 10;
}
result_integer.reverse();
BigDecimal {
integer_part: result_integer,
fractional_part: result_fractional,
}
}
pub fn multiply(&self, other: &BigDecimal) -> BigDecimal {
let mut result_integer = vec![0u8; self.integer_part.len() + other.integer_part.len()];
let mut result_fractional = vec![0u8; self.fractional_part.len() + other.fractional_part.len()];
for i in (0..self.integer_part.len()).rev() {
let mut carry = 0;
for j in (0..other.integer_part.len()).rev() {
let mul = self.integer_part[i] * other.integer_part[j] + result_integer[i + j + 1] + carry;
result_integer[i + j + 1] = mul % 10;
carry = mul / 10;
}
result_integer[i] = carry;
}
for i in (0..self.fractional_part.len()).rev() {
let mut carry = 0;
for j in (0..other.fractional_part.len()).rev() {
let mul = self.fractional_part[i] * other.fractional_part[j] + result_fractional[i + j + 1] + carry;
result_fractional[i + j + 1] = mul % 10;
carry = mul / 10;
}
result_fractional[i] = carry;
}
BigDecimal {
integer_part: result_integer,
fractional_part: result_fractional,
}
}
}

View file

@ -1,9 +1,5 @@
#[cfg(feature = "algebra")]
pub mod algebra;
#[test]
fn sum() {
let result = sum!(3, -1, 2);
assert_eq!(result, 4);
}
}
#[cfg(feature = "big_numbers")]
mod big_numbers;