Skip to content

Commit

Permalink
Implement Sub for Uint128 (closes #858)
Browse files Browse the repository at this point in the history
  • Loading branch information
uint committed Jun 16, 2021
1 parent 76a23fa commit 5edb2c0
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to

## [Unreleased]

### Added

- cosmwasm-std: Implement `Sub` and `SubAssign` for `Uint128`

### Removed

- cosmwasm-std: Make `Uint128` inner field private ([#905])
Expand Down
47 changes: 45 additions & 2 deletions packages/std/src/math/uint128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,22 @@ impl<'a> ops::Add<&'a Uint128> for Uint128 {
}
}

impl ops::Sub<Uint128> for Uint128 {
type Output = Self;

fn sub(self, rhs: Self) -> Self {
Uint128(self.u128().checked_sub(rhs.u128()).unwrap())
}
}

impl<'a> ops::Sub<&'a Uint128> for Uint128 {
type Output = Self;

fn sub(self, rhs: &'a Uint128) -> Self {
Uint128(self.u128().checked_sub(rhs.u128()).unwrap())
}
}

impl ops::AddAssign<Uint128> for Uint128 {
fn add_assign(&mut self, rhs: Uint128) {
self.0 = self.0.checked_add(rhs.u128()).unwrap();
Expand All @@ -218,6 +234,18 @@ impl<'a> ops::AddAssign<&'a Uint128> for Uint128 {
}
}

impl ops::SubAssign<Uint128> for Uint128 {
fn sub_assign(&mut self, rhs: Uint128) {
self.0 = self.0.checked_sub(rhs.u128()).unwrap();
}
}

impl<'a> ops::SubAssign<&'a Uint128> for Uint128 {
fn sub_assign(&mut self, rhs: &'a Uint128) {
self.0 = self.0.checked_sub(rhs.u128()).unwrap();
}
}

impl Uint128 {
/// Returns `self * numerator / denominator`
pub fn multiply_ratio<A: Into<u128>, B: Into<u128>>(
Expand Down Expand Up @@ -397,7 +425,8 @@ mod tests {
assert_eq!(a + &b, Uint128(35801));

// test - with owned and reference right hand side
assert_eq!((b.checked_sub(a)).unwrap(), Uint128(11111));
assert_eq!(b - a, Uint128(11111));
assert_eq!(b - &a, Uint128(11111));

// test += with owned and reference right hand side
let mut c = Uint128(300000);
Expand All @@ -407,6 +436,14 @@ mod tests {
d += &b;
assert_eq!(d, Uint128(323456));

// test -= with owned and reference right hand side
let mut c = Uint128(300000);
c -= b;
assert_eq!(c, Uint128(276544));
let mut d = Uint128(300000);
d -= &b;
assert_eq!(d, Uint128(276544));

// error result on underflow (- would produce negative result)
let underflow_result = a.checked_sub(b);
let OverflowError {
Expand All @@ -417,12 +454,18 @@ mod tests {

#[test]
#[should_panic]
fn uint128_math_overflow_panics() {
fn uint128_add_overflow_panics() {
// almost_max is 2^128 - 10
let almost_max = Uint128(340282366920938463463374607431768211446);
let _ = almost_max + Uint128(12);
}

#[test]
#[should_panic]
fn uint128_sub_overflow_panics() {
let _ = Uint128(1) - Uint128(2);
}

#[test]
fn uint128_multiply_ratio_works() {
let base = Uint128(500);
Expand Down

0 comments on commit 5edb2c0

Please sign in to comment.