Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3use std::ops::{AddAssign, MulAssign};
4
5// For implementing base10_digits() accessor on LitInt.
6pub(crate) struct BigInt {
7 digits: Vec<u8>,
8}
9
10impl 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
41impl 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
56impl 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}