From 1c553c0cdcaac30187d40155c36f796824815f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Silva?= <123550+andresilva@users.noreply.github.com> Date: Sun, 6 Jun 2021 09:07:29 +0100 Subject: [PATCH] arithmetic: fix PerThing pow (#9030) * arithmetic: add failing test for pow * arithmetic: fix PerThing::pow * Revert back to previous optimisations Co-authored-by: Gav Wood --- primitives/arithmetic/src/per_things.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/primitives/arithmetic/src/per_things.rs b/primitives/arithmetic/src/per_things.rs index 29d5d2be73a1c..80d556486d563 100644 --- a/primitives/arithmetic/src/per_things.rs +++ b/primitives/arithmetic/src/per_things.rs @@ -639,20 +639,20 @@ macro_rules! implement_per_thing { impl Pow for $name { type Output = Self; - fn pow(self, exp: usize) -> Self::Output { + fn pow(mut self, exp: usize) -> Self::Output { if exp == 0 || self.is_one() { return Self::one() } + let mut result = self; let mut exp = exp - 1; while exp > 0 && !result.is_zero() { - if exp % 2 == 0 { - result = result.square(); - exp /= 2; - } else { + if exp % 2 != 0 { result = result * self; exp -= 1; } + self = self.square(); + exp /= 2; } result } @@ -1107,11 +1107,13 @@ macro_rules! implement_per_thing { $name::from_parts($max / 2).square(), ); - // x^3 - assert_eq!( - $name::from_parts($max / 2).saturating_pow(3), - $name::from_parts($max / 8), - ); + // x^2 .. x^16 + for n in 1..=16 { + assert_eq!( + $name::from_parts($max / 2).saturating_pow(n), + $name::from_parts(($max as u128 / 2u128.pow(n as u32)) as $type), + ); + } // 0^n == 0 assert_eq!(