diff --git a/CHANGELOG.md b/CHANGELOG.md index 27ec8119e8..9a05d8a7a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ and this project adheres to - cosmwasm-std: Implement `saturating_add`/`sub`/`mul` for `Decimal`/`Decimal256`. - cosmwasm-std: Implement `MIN` const value for all `Uint` and `Decimal` types +- cosmwasm-std: Implement `checked_div_euclid` for + `Uint256`/`Uint512`/`Decimal`/`Decimal256` [#1334]: https://github.com/CosmWasm/cosmwasm/pull/1334 diff --git a/packages/std/src/math/decimal.rs b/packages/std/src/math/decimal.rs index a97bf29ead..ea06395066 100644 --- a/packages/std/src/math/decimal.rs +++ b/packages/std/src/math/decimal.rs @@ -289,6 +289,10 @@ impl Decimal { Decimal::checked_from_ratio(self.numerator(), other.numerator()) } + pub fn checked_div_euclid(self, other: Self) -> Result { + Ok(self.checked_div(other)?.floor()) + } + pub fn checked_rem(self, other: Self) -> Result { self.0 .checked_rem(other.0) @@ -1880,12 +1884,34 @@ mod tests { ); assert!(matches!( Decimal::MAX.checked_div(Decimal::zero()), - Err(CheckedFromRatioError::DivideByZero { .. }) + Err(CheckedFromRatioError::DivideByZero {}) )); assert!(matches!( Decimal::MAX.checked_div(Decimal::percent(1)), - Err(CheckedFromRatioError::Overflow { .. }) + Err(CheckedFromRatioError::Overflow {}) + )); + + // checked div euclid + assert!(matches!( + Decimal::MAX.checked_div_euclid(Decimal::zero()), + Err(CheckedFromRatioError::DivideByZero {}) + )); + assert!(matches!( + Decimal::MAX.checked_div_euclid(Decimal::percent(1)), + Err(CheckedFromRatioError::Overflow {}) )); + assert_eq!( + Decimal::percent(600) + .checked_div_euclid(Decimal::percent(200)) + .unwrap(), + Decimal::percent(300), + ); + assert_eq!( + Decimal::percent(1500) + .checked_div_euclid(Decimal::percent(700)) + .unwrap(), + Decimal::percent(200), + ); // checked rem assert_eq!( diff --git a/packages/std/src/math/decimal256.rs b/packages/std/src/math/decimal256.rs index eed988c18d..40f8095dde 100644 --- a/packages/std/src/math/decimal256.rs +++ b/packages/std/src/math/decimal256.rs @@ -302,6 +302,10 @@ impl Decimal256 { Decimal256::checked_from_ratio(self.numerator(), other.numerator()) } + pub fn checked_div_euclid(self, other: Self) -> Result { + Ok(self.checked_div(other)?.floor()) + } + pub fn checked_rem(self, other: Self) -> Result { self.0 .checked_rem(other.0) @@ -2034,6 +2038,28 @@ mod tests { Err(CheckedFromRatioError::Overflow { .. }) )); + // checked div euclid + assert!(matches!( + Decimal256::MAX.checked_div_euclid(Decimal256::zero()), + Err(CheckedFromRatioError::DivideByZero {}) + )); + assert!(matches!( + Decimal256::MAX.checked_div_euclid(Decimal256::percent(1)), + Err(CheckedFromRatioError::Overflow {}) + )); + assert_eq!( + Decimal256::percent(600) + .checked_div_euclid(Decimal256::percent(200)) + .unwrap(), + Decimal256::percent(300), + ); + assert_eq!( + Decimal256::percent(1500) + .checked_div_euclid(Decimal256::percent(700)) + .unwrap(), + Decimal256::percent(200), + ); + // checked rem assert_eq!( Decimal256::percent(402) diff --git a/packages/std/src/math/uint256.rs b/packages/std/src/math/uint256.rs index e1c14ac94a..3d7883b608 100644 --- a/packages/std/src/math/uint256.rs +++ b/packages/std/src/math/uint256.rs @@ -251,6 +251,10 @@ impl Uint256 { .ok_or_else(|| DivideByZeroError::new(self)) } + pub fn checked_div_euclid(self, other: Self) -> Result { + self.checked_div(other) + } + pub fn checked_rem(self, other: Self) -> Result { self.0 .checked_rem(other.0) @@ -1456,6 +1460,18 @@ mod tests { Uint256::from(6u32).checked_div(Uint256::from(2u32)), Ok(Uint256::from(3u32)), ); + assert!(matches!( + Uint256::MAX.checked_div_euclid(Uint256::from(0u32)), + Err(DivideByZeroError { .. }) + )); + assert_eq!( + Uint256::from(6u32).checked_div_euclid(Uint256::from(2u32)), + Ok(Uint256::from(3u32)), + ); + assert_eq!( + Uint256::from(7u32).checked_div_euclid(Uint256::from(2u32)), + Ok(Uint256::from(3u32)), + ); assert!(matches!( Uint256::MAX.checked_rem(Uint256::from(0u32)), Err(DivideByZeroError { .. }) diff --git a/packages/std/src/math/uint512.rs b/packages/std/src/math/uint512.rs index 2a66189b44..e53bad95d3 100644 --- a/packages/std/src/math/uint512.rs +++ b/packages/std/src/math/uint512.rs @@ -234,6 +234,10 @@ impl Uint512 { .ok_or_else(|| DivideByZeroError::new(self)) } + pub fn checked_div_euclid(self, other: Self) -> Result { + self.checked_div(other) + } + pub fn checked_rem(self, other: Self) -> Result { self.0 .checked_rem(other.0) @@ -1091,6 +1095,18 @@ mod tests { Uint512::from(6u32).checked_div(Uint512::from(2u32)), Ok(Uint512::from(3u32)), ); + assert!(matches!( + Uint512::MAX.checked_div_euclid(Uint512::from(0u32)), + Err(DivideByZeroError { .. }) + )); + assert_eq!( + Uint512::from(6u32).checked_div_euclid(Uint512::from(2u32)), + Ok(Uint512::from(3u32)), + ); + assert_eq!( + Uint512::from(7u32).checked_div_euclid(Uint512::from(2u32)), + Ok(Uint512::from(3u32)), + ); assert!(matches!( Uint512::MAX.checked_rem(Uint512::from(0u32)), Err(DivideByZeroError { .. })