X-Git-Url: https://git.ralfj.de/rust-101.git/blobdiff_plain/09a36e34a7b4f163c25fb971771bc4c7edd63e2b..369875f931d841112dd2b6651fc968bb6c569cdb:/solutions/src/bigint.rs diff --git a/solutions/src/bigint.rs b/solutions/src/bigint.rs index 0abb6b3..80ac63d 100644 --- a/solutions/src/bigint.rs +++ b/solutions/src/bigint.rs @@ -64,6 +64,26 @@ impl BigInt { BigInt { data: v } } + /// Increments the number by 1. Solution to 05.1. + pub fn inc1(&mut self) { + let mut idx = 0; + // This loop adds "(1 << idx)". If there is no more carry, we leave. + while idx < self.data.len() { + let cur = self.data[idx]; + let sum = u64::wrapping_add(cur, 1); + self.data[idx] = sum; + if sum >= cur { + // No overflow, we are done. + return; + } else { + // We need to go on. + idx += 1; + } + } + // If we came here, there is a last carry to add + self.data.push(1); + } + /// Increments the number by "by". pub fn inc(&mut self, mut by: u64) { let mut idx = 0; @@ -191,6 +211,7 @@ impl ops::Add for BigInt { #[cfg(test)] mod tests { + use std::u64; use super::overflowing_add; use super::BigInt; @@ -203,6 +224,21 @@ mod tests { assert_eq!(overflowing_add(1 << 63, (1 << 63) -1 , true), (0, true)); } + #[test] + fn test_inc1() { + let mut b = BigInt::new(0); + b.inc1(); + assert_eq!(b, BigInt::new(1)); + b.inc1(); + assert_eq!(b, BigInt::new(2)); + + b = BigInt::new(u64::MAX); + b.inc1(); + assert_eq!(b, BigInt::from_vec(vec![0, 1])); + b.inc1(); + assert_eq!(b, BigInt::from_vec(vec![1, 1])); + } + #[test] fn test_power_of_2() { assert_eq!(BigInt::power_of_2(0), BigInt::new(1));