Skip to content
This repository has been archived by the owner on May 22, 2023. It is now read-only.

Commit

Permalink
arithmetic: fix PerThing pow (paritytech#9030)
Browse files Browse the repository at this point in the history
* arithmetic: add failing test for pow

* arithmetic: fix PerThing::pow

* Revert back to previous optimisations

Co-authored-by: Gav Wood <gavin@parity.io>
  • Loading branch information
2 people authored and Andrei Navoichyk committed Sep 9, 2022
1 parent 9159cdb commit 1c553c0
Showing 1 changed file with 12 additions and 10 deletions.
22 changes: 12 additions & 10 deletions primitives/arithmetic/src/per_things.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,20 +639,20 @@ macro_rules! implement_per_thing {
impl Pow<usize> 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
}
Expand Down Expand Up @@ -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!(
Expand Down

0 comments on commit 1c553c0

Please sign in to comment.