Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/rust/syn/bigint.rs
38271 views
1
// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3
use std::ops::{AddAssign, MulAssign};
4
5
// For implementing base10_digits() accessor on LitInt.
6
pub(crate) struct BigInt {
7
digits: Vec<u8>,
8
}
9
10
impl BigInt {
11
pub(crate) fn new() -> Self {
12
BigInt { digits: Vec::new() }
13
}
14
15
pub(crate) fn to_string(&self) -> String {
16
let mut repr = String::with_capacity(self.digits.len());
17
18
let mut has_nonzero = false;
19
for digit in self.digits.iter().rev() {
20
has_nonzero |= *digit != 0;
21
if has_nonzero {
22
repr.push((*digit + b'0') as char);
23
}
24
}
25
26
if repr.is_empty() {
27
repr.push('0');
28
}
29
30
repr
31
}
32
33
fn reserve_two_digits(&mut self) {
34
let len = self.digits.len();
35
let desired =
36
len + !self.digits.ends_with(&[0, 0]) as usize + !self.digits.ends_with(&[0]) as usize;
37
self.digits.resize(desired, 0);
38
}
39
}
40
41
impl AddAssign<u8> for BigInt {
42
// Assumes increment <16.
43
fn add_assign(&mut self, mut increment: u8) {
44
self.reserve_two_digits();
45
46
let mut i = 0;
47
while increment > 0 {
48
let sum = self.digits[i] + increment;
49
self.digits[i] = sum % 10;
50
increment = sum / 10;
51
i += 1;
52
}
53
}
54
}
55
56
impl MulAssign<u8> for BigInt {
57
// Assumes base <=16.
58
fn mul_assign(&mut self, base: u8) {
59
self.reserve_two_digits();
60
61
let mut carry = 0;
62
for digit in &mut self.digits {
63
let prod = *digit * base + carry;
64
*digit = prod % 10;
65
carry = prod / 10;
66
}
67
}
68
}
69
70