diff --git a/CHANGELOG.md b/CHANGELOG.md index 045d57213b..9103aa0aed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to ### Added - cosmwasm-std: Add `Uint{64,128,256,512}::one`. +- cosmwasm-std: Add `Uint{64,128,256,512}::abs_diff` and + `Decimal{,256}::abs_diff` ([#1334]). + +[#1334]: https://github.com/CosmWasm/cosmwasm/pull/1334 ## [1.0.0] - 2022-05-14 diff --git a/packages/std/src/math/decimal.rs b/packages/std/src/math/decimal.rs index f426030711..497b29c926 100644 --- a/packages/std/src/math/decimal.rs +++ b/packages/std/src/math/decimal.rs @@ -258,6 +258,10 @@ impl Decimal { Decimal(inner.isqrt().checked_mul(Uint128::from(outer_mul)).unwrap()) }) } + + pub const fn abs_diff(self, other: Self) -> Self { + Self(self.0.abs_diff(other.0)) + } } impl Fraction for Decimal { @@ -1664,4 +1668,13 @@ mod tests { Decimal::percent(8765) ); } + + #[test] + fn decimal_abs_diff_works() { + let a = Decimal::percent(285); + let b = Decimal::percent(200); + let expected = Decimal::percent(85); + assert_eq!(a.abs_diff(b), expected); + assert_eq!(b.abs_diff(a), expected); + } } diff --git a/packages/std/src/math/decimal256.rs b/packages/std/src/math/decimal256.rs index 67d216b3e7..5b4804f5f1 100644 --- a/packages/std/src/math/decimal256.rs +++ b/packages/std/src/math/decimal256.rs @@ -270,6 +270,14 @@ impl Decimal256 { Self(inner.isqrt().checked_mul(outer_mul).unwrap()) }) } + + pub fn abs_diff(self, other: Self) -> Self { + if self < other { + other - self + } else { + self - other + } + } } impl Fraction for Decimal256 { @@ -1783,4 +1791,13 @@ mod tests { Decimal256::percent(8765) ); } + + #[test] + fn decimal256_abs_diff_works() { + let a = Decimal256::percent(285); + let b = Decimal256::percent(200); + let expected = Decimal256::percent(85); + assert_eq!(a.abs_diff(b), expected); + assert_eq!(b.abs_diff(a), expected); + } } diff --git a/packages/std/src/math/uint128.rs b/packages/std/src/math/uint128.rs index 11d214bddd..5aee2fc8f6 100644 --- a/packages/std/src/math/uint128.rs +++ b/packages/std/src/math/uint128.rs @@ -208,6 +208,14 @@ impl Uint128 { pub fn saturating_pow(self, other: u32) -> Self { Self(self.0.saturating_pow(other)) } + + pub const fn abs_diff(self, other: Self) -> Self { + Self(if self.0 < other.0 { + other.0 - self.0 + } else { + self.0 - other.0 + }) + } } // `From` is implemented manually instead of @@ -965,4 +973,13 @@ mod tests { a %= &b; assert_eq!(a, Uint128::from(1u32)); } + + #[test] + fn uint128_abs_diff_works() { + let a = Uint128::from(42u32); + let b = Uint128::from(5u32); + let expected = Uint128::from(37u32); + assert_eq!(a.abs_diff(b), expected); + assert_eq!(b.abs_diff(a), expected); + } } diff --git a/packages/std/src/math/uint256.rs b/packages/std/src/math/uint256.rs index a4b7c4b002..9150bed567 100644 --- a/packages/std/src/math/uint256.rs +++ b/packages/std/src/math/uint256.rs @@ -283,6 +283,14 @@ impl Uint256 { pub fn saturating_mul(self, other: Self) -> Self { Self(self.0.saturating_mul(other.0)) } + + pub fn abs_diff(self, other: Self) -> Self { + if self < other { + other - self + } else { + self - other + } + } } impl From for Uint256 { @@ -1516,4 +1524,13 @@ mod tests { a %= &b; assert_eq!(a, Uint256::from(1u32)); } + + #[test] + fn uint256_abs_diff_works() { + let a = Uint256::from(42u32); + let b = Uint256::from(5u32); + let expected = Uint256::from(37u32); + assert_eq!(a.abs_diff(b), expected); + assert_eq!(b.abs_diff(a), expected); + } } diff --git a/packages/std/src/math/uint512.rs b/packages/std/src/math/uint512.rs index a8779b7c91..ceeb7b8694 100644 --- a/packages/std/src/math/uint512.rs +++ b/packages/std/src/math/uint512.rs @@ -258,6 +258,14 @@ impl Uint512 { pub fn saturating_mul(self, other: Self) -> Self { Self(self.0.saturating_mul(other.0)) } + + pub fn abs_diff(self, other: Self) -> Self { + if self < other { + other - self + } else { + self - other + } + } } impl From for Uint512 { @@ -1151,4 +1159,13 @@ mod tests { a %= &b; assert_eq!(a, Uint512::from(1u32)); } + + #[test] + fn uint512_abs_diff_works() { + let a = Uint512::from(42u32); + let b = Uint512::from(5u32); + let expected = Uint512::from(37u32); + assert_eq!(a.abs_diff(b), expected); + assert_eq!(b.abs_diff(a), expected); + } } diff --git a/packages/std/src/math/uint64.rs b/packages/std/src/math/uint64.rs index cfe437f995..6bf19b2c3e 100644 --- a/packages/std/src/math/uint64.rs +++ b/packages/std/src/math/uint64.rs @@ -204,6 +204,14 @@ impl Uint64 { pub fn saturating_pow(self, other: u32) -> Self { Self(self.0.saturating_pow(other)) } + + pub const fn abs_diff(self, other: Self) -> Self { + Self(if self.0 < other.0 { + other.0 - self.0 + } else { + self.0 - other.0 + }) + } } // `From` is implemented manually instead of @@ -878,4 +886,13 @@ mod tests { a %= &b; assert_eq!(a, Uint64::from(1u32)); } + + #[test] + fn uint64_abs_diff_works() { + let a = Uint64::from(42u32); + let b = Uint64::from(5u32); + let expected = Uint64::from(37u32); + assert_eq!(a.abs_diff(b), expected); + assert_eq!(b.abs_diff(a), expected); + } }