From 02ecb6b37bb4c401ba1e8c77857a04edaf21735d Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 13 Jul 2016 11:29:18 +0200 Subject: [PATCH 1/2] pow uses shifts and zero comp --- util/bigint/src/uint.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/util/bigint/src/uint.rs b/util/bigint/src/uint.rs index 8e08e590a..b67c491fc 100644 --- a/util/bigint/src/uint.rs +++ b/util/bigint/src/uint.rs @@ -713,9 +713,8 @@ macro_rules! construct_uint { /// Fast exponentation by squaring /// https://en.wikipedia.org/wiki/Exponentiation_by_squaring fn overflowing_pow(self, expon: Self) -> (Self, bool) { - if expon == Self::zero() { - return (Self::one(), false) - } + if expon.is_zero() { return (Self::one(), false) } + let is_even = |x : &Self| x.low_u64() & 1 == 0; let u_one = Self::one(); @@ -728,11 +727,11 @@ macro_rules! construct_uint { while n > u_one { if is_even(&n) { x = overflowing!(x.overflowing_mul(x), overflow); - n = n / u_two; + n = n >> 1; } else { y = overflowing!(x.overflowing_mul(y), overflow); x = overflowing!(x.overflowing_mul(x), overflow); - n = (n - u_one) / u_two; + n = (n - u_one) >> 1; } } let res = overflowing!(x.overflowing_mul(y), overflow); From e75274df669dbf38a424f08d8092453e74aacc3a Mon Sep 17 00:00:00 2001 From: NikVolf Date: Wed, 13 Jul 2016 11:58:08 +0200 Subject: [PATCH 2/2] more pow opts --- util/bigint/src/uint.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/util/bigint/src/uint.rs b/util/bigint/src/uint.rs index b67c491fc..e3c27f80d 100644 --- a/util/bigint/src/uint.rs +++ b/util/bigint/src/uint.rs @@ -687,24 +687,25 @@ macro_rules! construct_uint { /// Fast exponentation by squaring /// https://en.wikipedia.org/wiki/Exponentiation_by_squaring fn pow(self, expon: Self) -> Self { - if expon == Self::zero() { + if expon.is_zero() { return Self::one() } let is_even = |x : &Self| x.low_u64() & 1 == 0; let u_one = Self::one(); - let u_two = Self::from(2); let mut y = u_one; let mut n = expon; let mut x = self; while n > u_one { if is_even(&n) { x = x * x; - n = n / u_two; + n = n >> 1; } else { y = x * y; x = x * x; - n = (n - u_one) / u_two; + // to reduce odd number by 1 we should just clear the last bit + n.0[$n_words-1] = n.0[$n_words-1] & ((!0u64)>>1); + n = n >> 1; } } x * y @@ -718,7 +719,6 @@ macro_rules! construct_uint { let is_even = |x : &Self| x.low_u64() & 1 == 0; let u_one = Self::one(); - let u_two = Self::from(2); let mut y = u_one; let mut n = expon; let mut x = self; @@ -1067,7 +1067,7 @@ macro_rules! construct_uint { impl fmt::Display for $name { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if *self == $name::zero() { + if self.is_zero() { return write!(f, "0"); } @@ -1075,7 +1075,7 @@ macro_rules! construct_uint { let mut current = *self; let ten = $name::from(10); - while current != $name::zero() { + while !current.is_zero() { s = format!("{}{}", (current % ten).low_u32(), s); current = current / ten; }