tweak the bigint
This commit is contained in:
parent
e3de039c39
commit
0ed2722260
1 changed files with 62 additions and 54 deletions
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue