struct S(); impl S { pub fn multiply(num1: String, num2: String) -> String { let l1 = num1.len(); let l2 = num2.len(); // get the longest one as num1 let (num1, num2) = if l1 < l2 { (num2, num1) } else { (num1, num2) }; if l1 == 0 || l2 == 0 { return "0".to_string(); } let tsize = l1.max(l2); let mut out: Vec = (0..(num1.len() + num2.len())) .into_iter() .map(|_| 0) .collect(); for (i2, d2) in num2.chars().rev().enumerate() { let mut mcarry = 0; let mut tmp: Vec = (0..i2).into_iter().map(|_| 0).collect(); tmp.reserve(tsize - i2); let d2 = d2.to_digit(10).unwrap(); for d1 in num1.chars().rev() { let d1 = d1.to_digit(10).unwrap(); let p = (d1 * d2) + mcarry; mcarry = p / 10; let p = p % 10; tmp.push(p); } if mcarry > 0 { tmp.push(mcarry); } Self::merge(&mut out, &tmp); } let s: String = out .into_iter() .rev() .skip_while(|d| *d == 0) // SAFETY: the input is guaranteed to be valid .map(|d| unsafe { char::from_digit(d, 10).unwrap_unchecked() }) .collect(); if s.is_empty() { "0".to_string() } else { s } } fn merge(out: &mut [u32], rhs: &[u32]) { // let mut acarry = 0; let len = rhs.len(); (0..len).for_each(|i| { let oi = out[i]; let ri = rhs[i]; let s = oi + ri + acarry; acarry = s / 10; let s = s % 10; out[i] = s; }); if acarry > 0 { out[len] = acarry; } } } fn main() { dbg!(S::multiply("2".to_string(), "4".to_string())); dbg!(S::multiply("27".to_string(), "49".to_string())); dbg!(S::multiply( "20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" .to_string(), "4000000000000000000000000000000000000000000000000000000000000000".to_string() )); dbg!(S::multiply("".to_string(), "88".to_string())); }