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 <gavin@parity.io>
This commit is contained in:
André Silva
2021-06-06 09:07:29 +01:00
committed by GitHub
parent c44b552d8f
commit f0c5699bc6
@@ -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
}
@@ -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!(