impl Mul + saturating_mul by converting in u64 (#1610)

This commit is contained in:
thiolliere
2019-01-29 13:36:34 +01:00
committed by Gav Wood
parent a541ee8c05
commit ecffe0c371
3 changed files with 30 additions and 18 deletions
+26 -14
View File
@@ -123,14 +123,7 @@ impl BuildStorage for StorageMap {
#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq)]
pub struct Permill(u32);
// TODO: impl Mul<Permill> for N where N: As<usize>
impl Permill {
/// Multiplication.
pub fn times<N: traits::As<u64> + ::rstd::ops::Mul<N, Output=N> + ::rstd::ops::Div<N, Output=N>>(self, b: N) -> N {
// TODO: handle overflows
b * <N as traits::As<u64>>::sa(self.0 as u64) / <N as traits::As<u64>>::sa(1000000)
}
/// Wraps the argument into `Permill` type.
pub fn from_millionths(x: u32) -> Permill { Permill(x) }
@@ -142,6 +135,16 @@ impl Permill {
pub fn from_fraction(x: f64) -> Permill { Permill((x * 1_000_000.0) as u32) }
}
impl<N> ::rstd::ops::Mul<N> for Permill
where
N: traits::As<u64>
{
type Output = N;
fn mul(self, b: N) -> Self::Output {
<N as traits::As<u64>>::sa(b.as_().saturating_mul(self.0 as u64) / 1_000_000)
}
}
#[cfg(feature = "std")]
impl From<f64> for Permill {
fn from(x: f64) -> Permill {
@@ -178,14 +181,7 @@ impl From<codec::Compact<Permill>> for Permill {
#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq)]
pub struct Perbill(u32);
// TODO: impl Mul<Perbill> for N where N: As<usize>
impl Perbill {
/// Attenuate `b` by self.
pub fn times<N: traits::As<u64> + ::rstd::ops::Mul<N, Output=N> + ::rstd::ops::Div<N, Output=N>>(self, b: N) -> N {
// TODO: handle overflows
b * <N as traits::As<u64>>::sa(self.0 as u64) / <N as traits::As<u64>>::sa(1_000_000_000)
}
/// Nothing.
pub fn zero() -> Perbill { Perbill(0) }
@@ -213,6 +209,16 @@ impl Perbill {
pub fn from_rational(n: f64, d: f64) -> Perbill { Perbill(((n / d).max(0.0).min(1.0) * 1_000_000_000.0) as u32) }
}
impl<N> ::rstd::ops::Mul<N> for Perbill
where
N: traits::As<u64>
{
type Output = N;
fn mul(self, b: N) -> Self::Output {
<N as traits::As<u64>>::sa(b.as_().saturating_mul(self.0 as u64) / 1_000_000_000)
}
}
#[cfg(feature = "std")]
impl From<f64> for Perbill {
fn from(x: f64) -> Perbill {
@@ -659,4 +665,10 @@ mod tests {
let encoded = data.encode();
assert_eq!(data, WithCompact::<super::Perbill>::decode(&mut &encoded[..]).unwrap());
}
#[test]
fn saturating_mul() {
assert_eq!(super::Perbill::one() * std::u64::MAX, std::u64::MAX/1_000_000_000);
assert_eq!(super::Permill::from_percent(100) * std::u64::MAX, std::u64::MAX/1_000_000);
}
}
+2 -2
View File
@@ -494,8 +494,8 @@ impl<T: Trait> Module<T> {
<session::Module<T>>::set_validators(vals);
// Update the balances for slashing/rewarding according to the stakes.
<CurrentOfflineSlash<T>>::put(Self::offline_slash().times(stake_range.1));
<CurrentSessionReward<T>>::put(Self::session_reward().times(stake_range.1));
<CurrentOfflineSlash<T>>::put(Self::offline_slash() * stake_range.1);
<CurrentSessionReward<T>>::put(Self::session_reward() * stake_range.1);
}
/// Call when a validator is determined to be offline. `count` is the
+2 -2
View File
@@ -201,7 +201,7 @@ impl<T: Trait> Module<T> {
/// The needed bond for a proposal whose spend is `value`.
fn calculate_bond(value: T::Balance) -> T::Balance {
Self::proposal_bond_minimum().max(Self::proposal_bond().times(value))
Self::proposal_bond_minimum().max(Self::proposal_bond() * value)
}
// Spend some money!
@@ -238,7 +238,7 @@ impl<T: Trait> Module<T> {
if !missed_any {
// burn some proportion of the remaining budget if we run a surplus.
let burn = Self::burn().times(budget_remaining).min(budget_remaining);
let burn = (Self::burn() * budget_remaining).min(budget_remaining);
budget_remaining -= burn;
Self::deposit_event(RawEvent::Burnt(burn))
}