Fix mul_acc. (#6145)

This commit is contained in:
Marcio Diaz
2020-05-26 18:03:29 +02:00
committed by GitHub
parent b64f55089d
commit 288953942e
+12 -2
View File
@@ -75,6 +75,11 @@ pub trait FixedPointNumber:
/// Consumes `self` and returns the inner raw value.
fn into_inner(self) -> Self::Inner;
/// Returns the negation.
fn negate(self) -> Self {
Self::from_inner(-self.into_inner())
}
/// Creates self from an integer number `int`.
///
/// Returns `Self::max` or `Self::min` if `int` exceeds accuracy.
@@ -163,7 +168,11 @@ pub trait FixedPointNumber:
///
/// Returns `N::min` or `N::max` if the multiplication or final result does not fit in `N`.
fn saturating_mul_acc_int<N: FixedPointOperand>(self, n: N) -> N {
self.saturating_mul_int(n).saturating_add(n)
if self.is_negative() && n > N::zero() {
n.saturating_sub(self.negate().saturating_mul_int(n))
} else {
self.saturating_mul_int(n).saturating_add(n)
}
}
/// Saturating absolute value.
@@ -1255,7 +1264,8 @@ macro_rules! implement_fixed {
let a = $name::saturating_from_rational(-1, 2);
assert_eq!(a.saturating_mul_acc_int(42i8), 21i8);
assert_eq!(a.saturating_mul_acc_int(u128::max_value() - 1), u128::max_value() - 1);
assert_eq!(a.saturating_mul_acc_int(42u8), 21u8);
assert_eq!(a.saturating_mul_acc_int(u128::max_value() - 1), u128::max_value() / 2);
}
#[test]