diff --git a/src/util/decimal.rs b/src/util/decimal.rs index fa44ebf..ee880e4 100644 --- a/src/util/decimal.rs +++ b/src/util/decimal.rs @@ -21,6 +21,8 @@ //! altcoins with different granularity may require a wider type. //! +use std::ops; + use serde::{ser, de}; use strason::Json; @@ -47,6 +49,37 @@ impl PartialOrd for Decimal { } } +impl ops::Add for Decimal { + type Output = Decimal; + + #[inline] + fn add(self, other: Decimal) -> Decimal { + if self.exponent > other.exponent { + Decimal { + mantissa: other.mantissa * 10i64.pow((self.exponent - other.exponent) as u32) + self.mantissa, + exponent: self.exponent + } + } else { + Decimal { + mantissa: self.mantissa * 10i64.pow((other.exponent - self.exponent) as u32) + other.mantissa, + exponent: other.exponent + } + } + } +} + +impl ops::Neg for Decimal { + type Output = Decimal; + #[inline] + fn neg(self) -> Decimal { Decimal { mantissa: -self.mantissa, exponent: self.exponent } } +} + +impl ops::Sub for Decimal { + type Output = Decimal; + #[inline] + fn sub(self, other: Decimal) -> Decimal { self + (-other) } +} + impl Decimal { /// Creates a new Decimal pub fn new(mantissa: i64, exponent: usize) -> Decimal { @@ -190,6 +223,20 @@ mod tests { assert!(d3 > d2); } + #[test] + fn arithmetic() { + let d1 = Decimal::new(5, 1); // 0.5 + let d2 = Decimal::new(-2, 2); // -0.02 + let d3 = Decimal::new(3, 0); // 3.0 + + assert_eq!(d1 + d2, Decimal::new(48, 2)); + assert_eq!(d1 - d2, Decimal::new(52, 2)); + assert_eq!(d1 + d3, Decimal::new(35, 1)); + assert_eq!(d1 - d3, Decimal::new(-25, 1)); + assert_eq!(d2 + d3, Decimal::new(298, 2)); + assert_eq!(d2 - d3, Decimal::new(-302, 2)); + } + #[test] fn json_parse() { let json = Json::from_str("0.00980000").unwrap();