From b06b0cde142509ec2437618e248c6d1aa6c6e64e Mon Sep 17 00:00:00 2001 From: Patrick Norton Date: Sun, 8 Aug 2021 09:58:53 -0400 Subject: [PATCH 1/2] Added BigUint::{is, next}_power_of_two() --- src/biguint.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/biguint.rs b/src/biguint.rs index 271a8837..ac5883ed 100644 --- a/src/biguint.rs +++ b/src/biguint.rs @@ -954,6 +954,40 @@ impl BigUint { self.normalize(); } } + + /// Returns `true` if and only if `self == 2^k` for some `k`. + pub fn is_power_of_two(&self) -> bool { + self.count_ones() == 1 + } + + /// Returns the smallest power of two greater than or equal to `self`. + pub fn next_power_of_two(mut self) -> BigUint { + match self.data.len() { + 0 => BigUint::one(), + 1 => { + match self.data[0].checked_next_power_of_two() { + Option::Some(x) => self.data[0] = x, + Option::None => { + self.data[0] = 0; + self.data.push(1); + } + } + self + } + i => { + match self.data[i - 1].checked_next_power_of_two() { + Option::Some(x) => self.data[i - 1] = x, + Option::None => { + self.data[i - 1] = 0; + self.data.push(1); + } + } + // Note: When we bump the MSRV to >= 1.50.0, we can replace this with slice::fill + self.data[..i - 1].iter_mut().for_each(|x| *x = 0); + self + } + } + } } pub(crate) trait IntDigits { From cd911e5c1310523d3142712720d72dcc32967b86 Mon Sep 17 00:00:00 2001 From: Patrick Norton Date: Fri, 27 Aug 2021 18:49:17 -0700 Subject: [PATCH 2/2] Added BigUint::to_next_power_of_two --- src/biguint.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/biguint.rs b/src/biguint.rs index ac5883ed..29cce658 100644 --- a/src/biguint.rs +++ b/src/biguint.rs @@ -988,6 +988,10 @@ impl BigUint { } } } + + pub fn to_next_power_of_two(&self) -> BigUint { + self.clone().next_power_of_two() + } } pub(crate) trait IntDigits {