From eda6f866be839a47418a9ed995fdc2d10bfbd1dd Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 1 Sep 2023 15:22:17 +0200 Subject: [PATCH 1/5] Add abs function for all signed ints --- packages/std/src/math/int128.rs | 5 +++++ packages/std/src/math/int256.rs | 5 +++++ packages/std/src/math/int512.rs | 5 +++++ packages/std/src/math/int64.rs | 5 +++++ 4 files changed, 20 insertions(+) diff --git a/packages/std/src/math/int128.rs b/packages/std/src/math/int128.rs index cc0b7c83b5..603c4fbd75 100644 --- a/packages/std/src/math/int128.rs +++ b/packages/std/src/math/int128.rs @@ -209,6 +209,11 @@ impl Int128 { pub const fn abs_diff(self, other: Self) -> Uint128 { Uint128(self.0.abs_diff(other.0)) } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn abs(self) -> Self { + Self(self.0.abs()) + } } impl From for Int128 { diff --git a/packages/std/src/math/int256.rs b/packages/std/src/math/int256.rs index 5616fcc2e7..30cf982ff5 100644 --- a/packages/std/src/math/int256.rs +++ b/packages/std/src/math/int256.rs @@ -258,6 +258,11 @@ impl Int256 { pub const fn abs_diff(self, other: Self) -> Uint256 { Uint256(self.0.abs_diff(other.0)) } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn abs(self) -> Self { + Self(self.0.abs()) + } } impl From for Int256 { diff --git a/packages/std/src/math/int512.rs b/packages/std/src/math/int512.rs index 2b122418e5..f1c9a2ce72 100644 --- a/packages/std/src/math/int512.rs +++ b/packages/std/src/math/int512.rs @@ -294,6 +294,11 @@ impl Int512 { pub const fn abs_diff(self, other: Self) -> Uint512 { Uint512(self.0.abs_diff(other.0)) } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn abs(self) -> Self { + Self(self.0.abs()) + } } impl From for Int512 { diff --git a/packages/std/src/math/int64.rs b/packages/std/src/math/int64.rs index 2e9ac7f68d..42c54e72d4 100644 --- a/packages/std/src/math/int64.rs +++ b/packages/std/src/math/int64.rs @@ -209,6 +209,11 @@ impl Int64 { pub const fn abs_diff(self, other: Self) -> Uint64 { Uint64(self.0.abs_diff(other.0)) } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn abs(self) -> Self { + Self(self.0.abs()) + } } impl From for Int64 { From b232b5a514bf940f982eeca20df5cd05c0a57517 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Fri, 1 Sep 2023 15:35:49 +0200 Subject: [PATCH 2/5] Add changelog entry --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4123a67dd..27a9e9302a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ and this project adheres to ## [Unreleased] +### Added + +- cosmwasm-std: Add `abs` for `Int{64,128,256,512}` ([#1854]). + +[#1854]: https://github.com/CosmWasm/cosmwasm/pull/1854 + ## [1.4.0] - 2023-09-04 ### Added From 034ade9dcea3464465d25e0a5c8056a7468b77d1 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 4 Sep 2023 09:55:12 +0200 Subject: [PATCH 3/5] Add tests --- packages/std/src/math/int128.rs | 16 ++++++++++++++++ packages/std/src/math/int256.rs | 16 ++++++++++++++++ packages/std/src/math/int512.rs | 16 ++++++++++++++++ packages/std/src/math/int64.rs | 16 ++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/packages/std/src/math/int128.rs b/packages/std/src/math/int128.rs index 603c4fbd75..e94db80043 100644 --- a/packages/std/src/math/int128.rs +++ b/packages/std/src/math/int128.rs @@ -1093,6 +1093,22 @@ mod tests { assert_eq!(c.abs_diff(b), Uint128::from(10u32)); } + #[test] + fn int128_abs_works() { + let a = Int128::from(42i32); + assert_eq!(a.abs(), a); + + let b = Int128::from(-42i32); + assert_eq!(b.abs(), a); + assert_eq!((Int128::MIN + Int128::one()).abs(), Int128::MAX); + } + + #[test] + #[should_panic = "attempt to negate with overflow"] + fn int128_abs_min_panics() { + _ = Int128::MIN.abs(); + } + #[test] #[should_panic = "attempt to negate with overflow"] fn int128_neg_min_panics() { diff --git a/packages/std/src/math/int256.rs b/packages/std/src/math/int256.rs index 30cf982ff5..312215930b 100644 --- a/packages/std/src/math/int256.rs +++ b/packages/std/src/math/int256.rs @@ -1176,6 +1176,22 @@ mod tests { assert_eq!(c.abs_diff(b), Uint256::from(10u32)); } + #[test] + fn int256_abs_works() { + let a = Int256::from(42i32); + assert_eq!(a.abs(), a); + + let b = Int256::from(-42i32); + assert_eq!(b.abs(), a); + assert_eq!((Int256::MIN + Int256::one()).abs(), Int256::MAX); + } + + #[test] + #[should_panic = "attempt to negate with overflow"] + fn int256_abs_min_panics() { + _ = Int256::MIN.abs(); + } + #[test] #[should_panic = "attempt to negate with overflow"] fn int256_neg_min_panics() { diff --git a/packages/std/src/math/int512.rs b/packages/std/src/math/int512.rs index f1c9a2ce72..a7759f8fe6 100644 --- a/packages/std/src/math/int512.rs +++ b/packages/std/src/math/int512.rs @@ -1229,6 +1229,22 @@ mod tests { assert_eq!(c.abs_diff(b), Uint512::from(10u32)); } + #[test] + fn int512_abs_works() { + let a = Int512::from(42i32); + assert_eq!(a.abs(), a); + + let b = Int512::from(-42i32); + assert_eq!(b.abs(), a); + assert_eq!((Int512::MIN + Int512::one()).abs(), Int512::MAX); + } + + #[test] + #[should_panic = "attempt to negate with overflow"] + fn int512_abs_min_panics() { + _ = Int512::MIN.abs(); + } + #[test] #[should_panic = "attempt to negate with overflow"] fn int512_neg_min_panics() { diff --git a/packages/std/src/math/int64.rs b/packages/std/src/math/int64.rs index 42c54e72d4..f87f719e07 100644 --- a/packages/std/src/math/int64.rs +++ b/packages/std/src/math/int64.rs @@ -1036,6 +1036,22 @@ mod tests { assert_eq!(c.abs_diff(b), Uint64::from(10u32)); } + #[test] + fn int64_abs_works() { + let a = Int64::from(42i32); + assert_eq!(a.abs(), a); + + let b = Int64::from(-42i32); + assert_eq!(b.abs(), a); + assert_eq!((Int64::MIN + Int64::one()).abs(), Int64::MAX); + } + + #[test] + #[should_panic = "attempt to negate with overflow"] + fn int64_abs_min_panics() { + _ = Int64::MIN.abs(); + } + #[test] #[should_panic = "attempt to negate with overflow"] fn int64_neg_min_panics() { From b57b8ced1d304dc3d8ac5a306890c1ed2ee602d7 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 4 Sep 2023 10:09:53 +0200 Subject: [PATCH 4/5] Add zero abs test --- packages/std/src/math/int128.rs | 2 ++ packages/std/src/math/int256.rs | 2 ++ packages/std/src/math/int512.rs | 2 ++ packages/std/src/math/int64.rs | 2 ++ 4 files changed, 8 insertions(+) diff --git a/packages/std/src/math/int128.rs b/packages/std/src/math/int128.rs index e94db80043..347924de06 100644 --- a/packages/std/src/math/int128.rs +++ b/packages/std/src/math/int128.rs @@ -1100,6 +1100,8 @@ mod tests { let b = Int128::from(-42i32); assert_eq!(b.abs(), a); + + assert_eq!(Int128::zero().abs(), Int128::zero()); assert_eq!((Int128::MIN + Int128::one()).abs(), Int128::MAX); } diff --git a/packages/std/src/math/int256.rs b/packages/std/src/math/int256.rs index 312215930b..c8ee50b442 100644 --- a/packages/std/src/math/int256.rs +++ b/packages/std/src/math/int256.rs @@ -1183,6 +1183,8 @@ mod tests { let b = Int256::from(-42i32); assert_eq!(b.abs(), a); + + assert_eq!(Int256::zero().abs(), Int256::zero()); assert_eq!((Int256::MIN + Int256::one()).abs(), Int256::MAX); } diff --git a/packages/std/src/math/int512.rs b/packages/std/src/math/int512.rs index a7759f8fe6..f9accee297 100644 --- a/packages/std/src/math/int512.rs +++ b/packages/std/src/math/int512.rs @@ -1236,6 +1236,8 @@ mod tests { let b = Int512::from(-42i32); assert_eq!(b.abs(), a); + + assert_eq!(Int512::zero().abs(), Int512::zero()); assert_eq!((Int512::MIN + Int512::one()).abs(), Int512::MAX); } diff --git a/packages/std/src/math/int64.rs b/packages/std/src/math/int64.rs index f87f719e07..12151eda2d 100644 --- a/packages/std/src/math/int64.rs +++ b/packages/std/src/math/int64.rs @@ -1043,6 +1043,8 @@ mod tests { let b = Int64::from(-42i32); assert_eq!(b.abs(), a); + + assert_eq!(Int64::zero().abs(), Int64::zero()); assert_eq!((Int64::MIN + Int64::one()).abs(), Int64::MAX); } From 6bab85f39f409d99eeb53c55b27df02a4c5d1487 Mon Sep 17 00:00:00 2001 From: Christoph Otter Date: Mon, 4 Sep 2023 10:55:02 +0200 Subject: [PATCH 5/5] Add unsigned_abs for Int{64,128,256,512} --- CHANGELOG.md | 3 ++- packages/std/src/math/int128.rs | 18 ++++++++++++++++++ packages/std/src/math/int256.rs | 18 ++++++++++++++++++ packages/std/src/math/int512.rs | 18 ++++++++++++++++++ packages/std/src/math/int64.rs | 18 ++++++++++++++++++ 5 files changed, 74 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27a9e9302a..e15bac5a8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ and this project adheres to ### Added -- cosmwasm-std: Add `abs` for `Int{64,128,256,512}` ([#1854]). +- cosmwasm-std: Add `abs` and `unsigned_abs` for `Int{64,128,256,512}` + ([#1854]). [#1854]: https://github.com/CosmWasm/cosmwasm/pull/1854 diff --git a/packages/std/src/math/int128.rs b/packages/std/src/math/int128.rs index 347924de06..1eb62c3f10 100644 --- a/packages/std/src/math/int128.rs +++ b/packages/std/src/math/int128.rs @@ -214,6 +214,11 @@ impl Int128 { pub const fn abs(self) -> Self { Self(self.0.abs()) } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn unsigned_abs(self) -> Uint128 { + Uint128(self.0.unsigned_abs()) + } } impl From for Int128 { @@ -1105,6 +1110,19 @@ mod tests { assert_eq!((Int128::MIN + Int128::one()).abs(), Int128::MAX); } + #[test] + fn int128_unsigned_abs_works() { + assert_eq!(Int128::zero().unsigned_abs(), Uint128::zero()); + assert_eq!(Int128::one().unsigned_abs(), Uint128::one()); + assert_eq!( + Int128::MIN.unsigned_abs(), + Uint128::new(Int128::MAX.0 as u128) + Uint128::one() + ); + + let v = Int128::from(-42i32); + assert_eq!(v.unsigned_abs(), v.abs_diff(Int128::zero())); + } + #[test] #[should_panic = "attempt to negate with overflow"] fn int128_abs_min_panics() { diff --git a/packages/std/src/math/int256.rs b/packages/std/src/math/int256.rs index c8ee50b442..78f9a15af5 100644 --- a/packages/std/src/math/int256.rs +++ b/packages/std/src/math/int256.rs @@ -263,6 +263,11 @@ impl Int256 { pub const fn abs(self) -> Self { Self(self.0.abs()) } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn unsigned_abs(self) -> Uint256 { + Uint256(self.0.unsigned_abs()) + } } impl From for Int256 { @@ -1188,6 +1193,19 @@ mod tests { assert_eq!((Int256::MIN + Int256::one()).abs(), Int256::MAX); } + #[test] + fn int256_unsigned_abs_works() { + assert_eq!(Int256::zero().unsigned_abs(), Uint256::zero()); + assert_eq!(Int256::one().unsigned_abs(), Uint256::one()); + assert_eq!( + Int256::MIN.unsigned_abs(), + Uint256::from_be_bytes(Int256::MAX.to_be_bytes()) + Uint256::one() + ); + + let v = Int256::from(-42i32); + assert_eq!(v.unsigned_abs(), v.abs_diff(Int256::zero())); + } + #[test] #[should_panic = "attempt to negate with overflow"] fn int256_abs_min_panics() { diff --git a/packages/std/src/math/int512.rs b/packages/std/src/math/int512.rs index f9accee297..6004a6f134 100644 --- a/packages/std/src/math/int512.rs +++ b/packages/std/src/math/int512.rs @@ -299,6 +299,11 @@ impl Int512 { pub const fn abs(self) -> Self { Self(self.0.abs()) } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn unsigned_abs(self) -> Uint512 { + Uint512(self.0.unsigned_abs()) + } } impl From for Int512 { @@ -1241,6 +1246,19 @@ mod tests { assert_eq!((Int512::MIN + Int512::one()).abs(), Int512::MAX); } + #[test] + fn int512_unsigned_abs_works() { + assert_eq!(Int512::zero().unsigned_abs(), Uint512::zero()); + assert_eq!(Int512::one().unsigned_abs(), Uint512::one()); + assert_eq!( + Int512::MIN.unsigned_abs(), + Uint512::from_be_bytes(Int512::MAX.to_be_bytes()) + Uint512::one() + ); + + let v = Int512::from(-42i32); + assert_eq!(v.unsigned_abs(), v.abs_diff(Int512::zero())); + } + #[test] #[should_panic = "attempt to negate with overflow"] fn int512_abs_min_panics() { diff --git a/packages/std/src/math/int64.rs b/packages/std/src/math/int64.rs index 12151eda2d..da4bc4f160 100644 --- a/packages/std/src/math/int64.rs +++ b/packages/std/src/math/int64.rs @@ -214,6 +214,11 @@ impl Int64 { pub const fn abs(self) -> Self { Self(self.0.abs()) } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn unsigned_abs(self) -> Uint64 { + Uint64(self.0.unsigned_abs()) + } } impl From for Int64 { @@ -1048,6 +1053,19 @@ mod tests { assert_eq!((Int64::MIN + Int64::one()).abs(), Int64::MAX); } + #[test] + fn int64_unsigned_abs_works() { + assert_eq!(Int64::zero().unsigned_abs(), Uint64::zero()); + assert_eq!(Int64::one().unsigned_abs(), Uint64::one()); + assert_eq!( + Int64::MIN.unsigned_abs(), + Uint64::new(Int64::MAX.0 as u64) + Uint64::one() + ); + + let v = Int64::from(-42i32); + assert_eq!(v.unsigned_abs(), v.abs_diff(Int64::zero())); + } + #[test] #[should_panic = "attempt to negate with overflow"] fn int64_abs_min_panics() {