tweak the bigint

This commit is contained in:
Joe Ardent 2022-10-29 13:37:04 -07:00
parent e3de039c39
commit 0ed2722260
1 changed files with 62 additions and 54 deletions

View File

@ -1,73 +1,81 @@
pub fn multiply(num1: String, num2: String) -> String { struct S();
//
let mut out: Vec<u32> = (0..(num1.len() + num2.len())) impl S {
.into_iter() pub fn multiply(num1: String, num2: String) -> String {
.map(|_| 0) let l1 = num1.len();
.collect(); let l2 = num2.len();
// get the longest one as num1
let (num1, num2) = if l1 < l2 { (num2, num1) } else { (num1, num2) };
let l1 = num1.len(); if l1 == 0 || l2 == 0 {
let l2 = num2.len(); return "0".to_string();
// get the longest one as num1
let (num1, num2) = if l1 < l2 { (num2, num1) } else { (num1, num2) };
for (i2, d2) in num2.chars().rev().enumerate() {
let mut mcarry = 0;
let mut tmp: Vec<u32> = (0..i2).into_iter().map(|_| 0).collect();
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 { let tsize = l1.max(l2);
tmp.push(mcarry);
let mut out: Vec<u32> = (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<u32> = (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);
} }
merge(&mut out, &tmp);
} let s: String = out
while let Some(last) = out.last() { .into_iter()
if *last == 0 { .rev()
let len = out.len() - 1; .skip_while(|d| *d == 0)
out = out[0..len].to_vec(); // 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 { } else {
break; s
} }
} }
if out.is_empty() {
out.push(0);
}
out.iter().rev().map(|d| d.to_string()).collect() 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;
});
fn merge(out: &mut [u32], rhs: &[u32]) { if acarry > 0 {
// out[len] = acarry;
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() { fn main() {
dbg!(multiply("2".to_string(), "4".to_string())); dbg!(S::multiply("2".to_string(), "4".to_string()));
dbg!(multiply("27".to_string(), "49".to_string())); dbg!(S::multiply("27".to_string(), "49".to_string()));
dbg!(multiply( dbg!(S::multiply(
"20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
.to_string(), .to_string(),
"4000000000000000000000000000000000000000000000000000000000000000".to_string() "4000000000000000000000000000000000000000000000000000000000000000".to_string()
)); ));
dbg!(multiply("0".to_string(), "8".to_string())); dbg!(S::multiply("".to_string(), "88".to_string()));
} }