Skip to content

Commit

Permalink
Documented Long
Browse files Browse the repository at this point in the history
  • Loading branch information
tfpf committed Aug 22, 2024
1 parent 00d8b69 commit be3f504
Showing 1 changed file with 38 additions and 3 deletions.
41 changes: 38 additions & 3 deletions src/utils/objects/long.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ pub struct Long {
digits: Vec<u32>,
}
impl Long {
/// Construct an arbitrary-precision integer from a big-endian string of
/// decimal digits.

/// Construct an arbitrary-precision integer.
///
/// * `s`
/// * `s` Big-endian string of decimal digits.
pub fn new(s: &str) -> Long {
let mut long = Long { digits: vec![] };
let mut idx = s.len();
Expand All @@ -27,15 +27,23 @@ impl Long {
}
long
}

/// Construct an arbitrary-precision integer.
///
/// * `digit` Least significant digit in base 1_000_000_000.
pub fn from(digit: u32) -> Long {
if digit >= 1_000_000_000 {
panic!("argument is too large to be a digit of this arbitrary-precision type");
}
Long { digits: vec![digit] }
}

/// Construct an arbitrary-precision integer whose decimal representation
/// is the reverse of the current one.
pub fn reverse(&self) -> Long {
Long::new(&self.to_string().chars().rev().collect::<String>())
}

/// Calculate the factorial of a non-negative number.
///
/// * `num` Number whose factorial is to be calculated.
Expand Down Expand Up @@ -64,6 +72,7 @@ impl Long {
}
result
}

/// Obtain the number of decimal digits of this number (i.e. its length).
pub fn len(&self) -> usize {
match self.digits.len() {
Expand All @@ -72,13 +81,15 @@ impl Long {
len => (len - 1) * 9 + self.digits.last().unwrap().to_string().len(),
}
}

/// Calculate the sum of all decimal digits of this number.
pub fn sum(&self) -> i64 {
self.digits
.iter()
.map(|&digit| utils::Digits::new(digit as i64).sum::<i64>())
.sum()
}

/// Raise this number to the given power.
///
/// * `exp` Power.
Expand All @@ -104,6 +115,14 @@ impl Long {
base = &base * &base;
}
}

/// Add two digits in base 1_000_000_000.
///
/// * `a`
/// * `b`
/// * `carry` Carried unit to be added.
///
/// Returns the sum of the digits in base 1_000_000_000 and the new carry.
fn adc(a: u32, b: u32, carry: bool) -> (u32, bool) {
let sum = a + b + carry as u32;
if sum >= 1_000_000_000 {
Expand All @@ -112,11 +131,21 @@ impl Long {
(sum, false)
}
}

/// Multiply two digits in base 1_000_000_000.
///
/// * `a`
/// * `b`
/// * `carry` Carried digit to be added.
///
/// Returns the product of the digits in base 1_000_000_000 and the new
/// carry.
fn mlc(a: u32, b: u32, carry: u32) -> (u32, u32) {
let product = a as u64 * b as u64 + carry as u64;
((product % 1_000_000_000) as u32, (product / 1_000_000_000) as u32)
}
}

impl std::ops::AddAssign<&Long> for Long {
fn add_assign(&mut self, other: &Long) {
self.digits
Expand All @@ -134,6 +163,7 @@ impl std::ops::AddAssign<&Long> for Long {
}
}
}

impl std::ops::Add<&Long> for &Long {
type Output = Long;
fn add(self, other: &Long) -> Long {
Expand All @@ -142,6 +172,7 @@ impl std::ops::Add<&Long> for &Long {
result
}
}

impl std::ops::MulAssign<u32> for Long {
fn mul_assign(&mut self, other: u32) {
let mut carry = 0;
Expand All @@ -154,6 +185,7 @@ impl std::ops::MulAssign<u32> for Long {
}
}
}

impl std::ops::Mul<u32> for &Long {
type Output = Long;
fn mul(self, other: u32) -> Long {
Expand All @@ -162,6 +194,7 @@ impl std::ops::Mul<u32> for &Long {
result
}
}

impl std::ops::Mul<&Long> for &Long {
type Output = Long;
fn mul(self, other: &Long) -> Long {
Expand All @@ -182,6 +215,7 @@ impl std::ops::Mul<&Long> for &Long {
result
}
}

impl std::fmt::Display for Long {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
self.digits
Expand All @@ -199,6 +233,7 @@ impl std::fmt::Display for Long {
})
}
}

impl std::fmt::Debug for Long {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let result = write!(f, "digits = |");
Expand Down

0 comments on commit be3f504

Please sign in to comment.