Skip to content
Snippets Groups Projects
Commit e8835d64 authored by Joseph Mark's avatar Joseph Mark Committed by GitHub
Browse files

Extend PerThing + Saturating (#5281)


* Extend PerThing + Saturating

* Add saturating_pow to Saturating
* Add saturating_truncating_mul to PerThing (rounding-down mul)
* Add saturating_reciprocal_mul to PerThing (divide x by perthing)
* Provide default methods where possible

* Restore const functions

* Fix test

* Update primitives/arithmetic/src/per_things.rs

Co-Authored-By: default avatarKian Paimani <5588131+kianenigma@users.noreply.github.com>

* Add comment and test verifying no overflow

* Formatting

* Fix possible overflow and change type constraint

* Use overflow pruning for all mul

* Formatting and comments

* Improve comments and names

* Comments in `rational_mul_correction` explain overflow aversion.

* Test rational_mul_correction

* Formatting

* Docs and formatting

* Add new trait methods to Perthing type impl

* Fix signature

* saturating_pow for Delegations

* Add missing trait method to impl

Co-authored-by: default avatarKian Paimani <5588131+kianenigma@users.noreply.github.com>
parent d7ffef43
No related merge requests found
......@@ -62,6 +62,13 @@ impl<Balance: Saturating> Saturating for Delegations<Balance> {
capital: self.capital.saturating_mul(o.capital),
}
}
fn saturating_pow(self, exp: usize) -> Self {
Self {
votes: self.votes.saturating_pow(exp),
capital: self.capital.saturating_pow(exp),
}
}
}
impl<
......
......@@ -110,12 +110,18 @@ impl Saturating for Fixed64 {
fn saturating_add(self, rhs: Self) -> Self {
Self(self.0.saturating_add(rhs.0))
}
fn saturating_mul(self, rhs: Self) -> Self {
Self(self.0.saturating_mul(rhs.0) / DIV)
}
fn saturating_sub(self, rhs: Self) -> Self {
Self(self.0.saturating_sub(rhs.0))
}
fn saturating_pow(self, exp: usize) -> Self {
Self(self.0.saturating_pow(exp as u32))
}
}
/// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait
......
This diff is collapsed.
......@@ -21,7 +21,7 @@ use codec::HasCompact;
pub use integer_sqrt::IntegerSquareRoot;
pub use num_traits::{
Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
CheckedShl, CheckedShr
CheckedShl, CheckedShr, checked_pow
};
use sp_std::ops::{
Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign,
......@@ -104,29 +104,41 @@ impl<T: Bounded + Sized, S: TryInto<T> + Sized> UniqueSaturatedInto<T> for S {
}
}
/// Simple trait to use checked mul and max value to give a saturated mul operation over
/// supported types.
/// Saturating arithmetic operations, returning maximum or minimum values instead of overflowing.
pub trait Saturating {
/// Saturated addition - if the product can't fit in the type then just use max-value.
fn saturating_add(self, o: Self) -> Self;
/// Saturated subtraction - if the product can't fit in the type then just use max-value.
fn saturating_sub(self, o: Self) -> Self;
/// Saturated multiply - if the product can't fit in the type then just use max-value.
fn saturating_mul(self, o: Self) -> Self;
/// Saturating addition. Compute `self + rhs`, saturating at the numeric bounds instead of
/// overflowing.
fn saturating_add(self, rhs: Self) -> Self;
/// Saturating subtraction. Compute `self - rhs`, saturating at the numeric bounds instead of
/// overflowing.
fn saturating_sub(self, rhs: Self) -> Self;
/// Saturating multiply. Compute `self * rhs`, saturating at the numeric bounds instead of
/// overflowing.
fn saturating_mul(self, rhs: Self) -> Self;
/// Saturating exponentiation. Compute `self.pow(exp)`, saturating at the numeric bounds
/// instead of overflowing.
fn saturating_pow(self, exp: usize) -> Self;
}
impl<T: CheckedMul + Bounded + num_traits::Saturating> Saturating for T {
impl<T: Clone + One + CheckedMul + Bounded + num_traits::Saturating> Saturating for T {
fn saturating_add(self, o: Self) -> Self {
<Self as num_traits::Saturating>::saturating_add(self, o)
}
fn saturating_sub(self, o: Self) -> Self {
<Self as num_traits::Saturating>::saturating_sub(self, o)
}
fn saturating_mul(self, o: Self) -> Self {
self.checked_mul(&o).unwrap_or_else(Bounded::max_value)
}
fn saturating_pow(self, exp: usize) -> Self {
checked_pow(self, exp).unwrap_or_else(Bounded::max_value)
}
}
/// Convenience type to work around the highly unergonomic syntax needed
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment