vertical_multiplication/steps/
mod.rs1use std::{
2 fmt::{Display, Formatter},
3 ops::Mul,
4};
5
6use num::{BigInt, Integer, Signed, ToPrimitive};
7
8mod shift_add;
9mod steps;
10
11#[derive(Debug)]
13pub struct MultiplicationSteps {
14 base: u32,
15 lhs: BigInt,
16 rhs: BigInt,
17 result: BigInt,
18 steps: Vec<ShiftAdd>,
19}
20
21#[derive(Debug)]
23pub struct ShiftAdd {
24 result: BigInt,
26 tail_digits: usize,
28}
29
30pub fn v_mul_detailed(a: &BigInt, b: &BigInt, base: u32) -> MultiplicationSteps {
32 let lhs = get_digits_rev(a, base);
33 let rhs = get_digits_rev(b, base);
34 let mut steps = MultiplicationSteps::new(a, b).with_base(base);
35 for (tail_rhs, dx) in rhs.iter().enumerate() {
36 for (tail_lhs, dy) in lhs.iter().enumerate() {
37 steps.push_step(ShiftAdd::new(dx.mul(dy), tail_rhs + tail_lhs))
38 }
39 }
40 steps
41}
42
43pub fn v_mul(a: &BigInt, b: &BigInt, base: u32) -> MultiplicationSteps {
45 let rhs = get_digits_rev(b, base);
46 let mut steps = MultiplicationSteps::new(a, b).with_base(base);
47 for (tail_rhs, dy) in rhs.iter().enumerate() {
48 steps.push_step(ShiftAdd::new(a.mul(BigInt::from(*dy)), tail_rhs))
49 }
50 steps
51}
52
53fn get_digits_rev(num: &BigInt, base: u32) -> Vec<usize> {
54 let mut digits = Vec::new();
55 let mut num = num.clone();
56 while num.is_positive() {
57 let (q, r) = num.div_rem(&BigInt::from(base));
58 digits.push(r.to_usize().unwrap());
59 num = q;
60 }
61 digits
62}