1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
use crate::utils;

pub fn add(base: u16, numb1: &[u16], numb2: &[u16]) -> Vec<u16> {
    let ne1 = numb1[0] == 1;
    let ne2 = numb2[0] == 1;

    let numb1 = abs(numb1);
    let numb2 = abs(numb2);

    if !ne1 && !ne2 {
        // this will be positive
        let mut digits = utils::add(base, &numb1, &numb2);
        digits.insert(0, 0);
        digits
    } else if ne1 && ne2 {
        // this will be negative
        let mut digits = utils::add(base, &numb1, &numb2);
        digits.insert(0, 1);
        digits
    } else if !ne1 && ne2 && utils::greater_than(&numb1, &numb2) {
        // this will be positive
        let mut digits = utils::subtract(base, &numb1, &numb2);
        digits.insert(0, 0);
        digits
    } else if !ne1 && ne2 && !utils::greater_than(&numb1, &numb2) {
        // this will be negative
        let mut digits = utils::subtract(base, &numb2, &numb1);
        digits.insert(0, 1);
        digits
    } else if ne1 && !ne2 && utils::greater_than(&numb1, &numb2) {
        // this will be negative
        let mut digits = utils::subtract(base, &numb1, &numb2);
        digits.insert(0, 1);
        digits
    } else if ne1 && !ne2 && !utils::greater_than(&numb1, &numb2) {
        // this will be positive
        let mut digits = utils::subtract(base, &numb2, &numb1);
        digits.insert(0, 0);
        digits
    } else {
        unreachable!();
    }
}

pub fn subtract(base: u16, numb1: &[u16], numb2: &[u16]) -> Vec<u16> {
    let ne1 = numb1[0] == 1;
    let ne2 = numb2[0] == 1;

    let numb1 = abs(numb1);
    let numb2 = abs(numb2);

    if !ne1 && !ne2 && utils::greater_than(&numb1, &numb2) {
        // this will be positive
        let mut digits = utils::subtract(base, &numb1, &numb2);
        digits.insert(0, 0);
        digits
    } else if !ne1 && !ne2 && !utils::greater_than(&numb1, &numb2) {
        // this will be negative
        let mut digits = utils::subtract(base, &numb2, &numb1);
        digits.insert(0, 1);
        digits
    } else if ne1 && !ne2 {
        // this will be negative
        let mut digits = utils::add(base, &numb1, &numb2);
        digits.insert(0, 1);
        digits
    } else if !ne1 && ne2 {
        // this will be positive
        let mut digits = utils::add(base, &numb1, &numb2);
        digits.insert(0, 0);
        digits
    } else if ne1 && ne2 && utils::greater_than(&numb1, &numb2) {
        // this will be negative
        let mut digits = utils::subtract(base, &numb1, &numb2);
        digits.insert(0, 1);
        digits
    } else if ne1 && ne2 && !utils::greater_than(&numb1, &numb2) {
        // this will be positive
        let mut digits = utils::subtract(base, &numb2, &numb1);
        digits.insert(0, 0);
        digits
    } else {
        unreachable!()
    }
}

pub fn div(base: u16, numb1: &[u16], numb2: &[u16]) -> (Vec<u16>, Vec<u16>) {
    let ne1 = numb1[0] == 1;
    let ne2 = numb2[0] == 1;

    let numb1 = abs(numb1);
    let numb2 = abs(numb2);

    if (ne1 && ne2) || (!ne1 && !ne2) {
        // this will be positive
        let (mut quotient, mut remainder) = utils::div(base, &numb1, &numb2);
        quotient.insert(0, 0);
        remainder.insert(0, 0);
        (quotient, remainder)
    } else if (ne1 && !ne2) || (!ne1 && ne2) {
        // this will be negative
        let (mut qoutient, mut remainder) = utils::div(base, &numb1, &numb2);
        qoutient.insert(0, 1);
        remainder.insert(0, 1);
        (qoutient, remainder)
    } else {
        unreachable!()
    }
}

pub fn mul(base: u16, numb1: &[u16], numb2: &[u16]) -> Vec<u16> {
    let ne1 = numb1[0] == 1;
    let ne2 = numb2[0] == 1;

    let numb1 = abs(numb1);
    let numb2 = abs(numb2);

    if (ne1 && ne2) || (!ne1 && !ne2) {
        // this will be positive
        let mut digits = utils::mul(base, &numb1, &numb2);
        digits.insert(0, 0);
        digits
    } else if (!ne1 && ne2) || (ne1 && !ne2) {
        // this will be negative
        let mut digits = utils::mul(base, &numb1, &numb2);
        digits.insert(0, 1);
        digits
    } else {
        unreachable!()
    }
}

pub fn abs_greater_than(numb1: &[u16], numb2: &[u16]) -> bool {
    let numb1 = abs(numb1);
    let numb2 = abs(numb2);

    utils::greater_than(&numb1, &numb2)
}

pub fn trim_base_vec(vec: &mut Vec<u16>) -> Vec<u16> {
    let positive = vec[0] == 0;
    let mut digits = utils::trim_base_vec(vec);
    if positive {
        // a positive number should start with 0
        digits.insert(0, 0);
    }
    digits
}

pub fn abs(number: &[u16]) -> Vec<u16> {
    let mut number = number.to_owned();
    number.remove(0);
    number
}