|
|
|
@ -125,6 +125,24 @@ impl Number for DynNum { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn parse(str: &str) -> Self { |
|
|
|
|
// Separate implementation required as e.g. Fixed from_str_radix does not support decimals
|
|
|
|
|
match get_kind() { |
|
|
|
|
NumKind::Fixed => { |
|
|
|
|
DynNum { fixed: ManuallyDrop::new(Fixed::parse(str)) } |
|
|
|
|
} |
|
|
|
|
NumKind::GuardedFixed => { |
|
|
|
|
DynNum { gfixed: ManuallyDrop::new(GuardedFixed::parse(str)) } |
|
|
|
|
} |
|
|
|
|
NumKind::NativeFloat64 => { |
|
|
|
|
DynNum { float64: NativeFloat64::parse(str) } |
|
|
|
|
} |
|
|
|
|
NumKind::Rational => { |
|
|
|
|
DynNum { rational: ManuallyDrop::new(Rational::parse(str)) } |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fn describe() -> String { impl_assoc_nowrap!(describe) } |
|
|
|
|
fn pow_assign(&mut self, exponent: i32) { impl_1arg_nowrap!(self, exponent, pow_assign) } |
|
|
|
|
fn floor_mut(&mut self, dps: usize) { impl_1arg_nowrap!(self, dps, floor_mut) } |
|
|
|
@ -132,6 +150,37 @@ impl Number for DynNum { |
|
|
|
|
fn round_mut(&mut self, dps: usize) { impl_1arg_nowrap!(self, dps, round_mut) } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn rounding() { |
|
|
|
|
// Must specify scope so references are dropped at the correct time, before KIND is changed
|
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Fixed); |
|
|
|
|
Fixed::set_dps(5); |
|
|
|
|
let mut x = DynNum::parse("55.557"); x.floor_mut(2); assert_eq!(x, DynNum::parse("55.55")); |
|
|
|
|
let mut x = DynNum::parse("55.557"); x.ceil_mut(2); assert_eq!(x, DynNum::parse("55.56")); |
|
|
|
|
let mut x = DynNum::parse("55.557"); x.round_mut(2); assert_eq!(x, DynNum::parse("55.56")); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::GuardedFixed); |
|
|
|
|
GuardedFixed::set_dps(5); |
|
|
|
|
let mut x = DynNum::parse("55.557"); x.floor_mut(2); assert_eq!(x, DynNum::parse("55.55")); |
|
|
|
|
let mut x = DynNum::parse("55.557"); x.ceil_mut(2); assert_eq!(x, DynNum::parse("55.56")); |
|
|
|
|
let mut x = DynNum::parse("55.557"); x.round_mut(2); assert_eq!(x, DynNum::parse("55.56")); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::NativeFloat64); |
|
|
|
|
let mut x = DynNum::parse("55.557"); x.floor_mut(2); assert_eq!(x, DynNum::parse("55.55")); |
|
|
|
|
let mut x = DynNum::parse("55.557"); x.ceil_mut(2); assert_eq!(x, DynNum::parse("55.56")); |
|
|
|
|
let mut x = DynNum::parse("55.557"); x.round_mut(2); assert_eq!(x, DynNum::parse("55.56")); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Rational); |
|
|
|
|
let mut x = DynNum::parse("55.557"); x.floor_mut(2); assert_eq!(x, DynNum::parse("55.55")); |
|
|
|
|
let mut x = DynNum::parse("55.557"); x.ceil_mut(2); assert_eq!(x, DynNum::parse("55.56")); |
|
|
|
|
let mut x = DynNum::parse("55.557"); x.round_mut(2); assert_eq!(x, DynNum::parse("55.56")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl Drop for DynNum { |
|
|
|
|
fn drop(&mut self) { |
|
|
|
|
// Safety: Access only correct union field
|
|
|
|
@ -251,6 +300,40 @@ impl Assign<&Self> for DynNum { |
|
|
|
|
fn assign(&mut self, src: &Self) { impl_1other_nowrap_mut!(self, src, assign) } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn assign() { |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Fixed); |
|
|
|
|
Fixed::set_dps(2); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
let mut x = a.clone(); x.assign(b.clone()); assert_eq!(x, b); |
|
|
|
|
let mut x = a.clone(); x.assign(&b); assert_eq!(x, b); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::GuardedFixed); |
|
|
|
|
GuardedFixed::set_dps(2); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
let mut x = a.clone(); x.assign(b.clone()); assert_eq!(x, b); |
|
|
|
|
let mut x = a.clone(); x.assign(&b); assert_eq!(x, b); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::NativeFloat64); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
let mut x = a.clone(); x.assign(b.clone()); assert_eq!(x, b); |
|
|
|
|
let mut x = a.clone(); x.assign(&b); assert_eq!(x, b); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Rational); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
let mut x = a.clone(); x.assign(b.clone()); assert_eq!(x, b); |
|
|
|
|
let mut x = a.clone(); x.assign(&b); assert_eq!(x, b); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl From<usize> for DynNum { |
|
|
|
|
fn from(n: usize) -> Self { |
|
|
|
|
match get_kind() { |
|
|
|
@ -275,7 +358,52 @@ impl fmt::Display for DynNum { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl fmt::Debug for DynNum { |
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { impl_1arg_nowrap!(self, f, fmt) } |
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
|
|
|
|
// Safety: Access only correct union field
|
|
|
|
|
unsafe { |
|
|
|
|
match get_kind() { |
|
|
|
|
NumKind::Fixed => { |
|
|
|
|
self.fixed.deref().fmt(f) |
|
|
|
|
} |
|
|
|
|
NumKind::GuardedFixed => { |
|
|
|
|
self.gfixed.deref().fmt(f) |
|
|
|
|
} |
|
|
|
|
NumKind::NativeFloat64 => { |
|
|
|
|
self.float64.fmt(f) |
|
|
|
|
} |
|
|
|
|
NumKind::Rational => { |
|
|
|
|
self.rational.deref().fmt(f) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn display_debug() { |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Fixed); |
|
|
|
|
Fixed::set_dps(2); |
|
|
|
|
let x = DynNum::parse("123.4"); assert_eq!(format!("{}", x), "123.40"); |
|
|
|
|
let x = DynNum::parse("123.4"); assert_eq!(format!("{:?}", x), "Fixed(12340)"); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::GuardedFixed); |
|
|
|
|
GuardedFixed::set_dps(2); |
|
|
|
|
let x = DynNum::parse("123.4"); assert_eq!(format!("{}", x), "123.40"); |
|
|
|
|
let x = DynNum::parse("123.4"); assert_eq!(format!("{:?}", x), "GuardedFixed(1234000)"); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::NativeFloat64); |
|
|
|
|
let x = DynNum::parse("123.4"); assert_eq!(format!("{}", x), format!("{}", 123.40_f64)); |
|
|
|
|
let x = DynNum::parse("123.4"); assert_eq!(format!("{:?}", x), format!("NativeFloat64({})", 123.40_f64)); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Rational); |
|
|
|
|
let x = DynNum::parse("123.4"); assert_eq!(format!("{}", x), "617/5"); |
|
|
|
|
let x = DynNum::parse("123.4"); assert_eq!(format!("{:.2}", x), "123.40"); |
|
|
|
|
let x = DynNum::parse("123.4"); assert_eq!(format!("{:?}", x), "Rational(617/5)"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl PartialEq for DynNum { |
|
|
|
@ -395,6 +523,52 @@ impl ops::Rem for DynNum { |
|
|
|
|
fn rem(self, rhs: Self) -> Self::Output { impl_1other_wrap!(self, rhs, rem) } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn arith_owned_owned() { |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Fixed); |
|
|
|
|
Fixed::set_dps(2); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
assert_eq!(a.clone() + b.clone(), DynNum::parse("802.35")); |
|
|
|
|
assert_eq!(a.clone() - b.clone(), DynNum::parse("-555.45")); |
|
|
|
|
assert_eq!(a.clone() * b.clone(), DynNum::parse("83810.20")); // = 83810.205 rounds to 83810.20
|
|
|
|
|
assert_eq!(a.clone() / b.clone(), DynNum::parse("0.18")); |
|
|
|
|
assert_eq!(b.clone() % a.clone(), DynNum::parse("61.65")); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::GuardedFixed); |
|
|
|
|
GuardedFixed::set_dps(2); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
assert_eq!(a.clone() + b.clone(), DynNum::parse("802.35")); |
|
|
|
|
assert_eq!(a.clone() - b.clone(), DynNum::parse("-555.45")); |
|
|
|
|
assert_eq!(a.clone() * b.clone(), DynNum::parse("83810.205")); // Must compare to 3 d.p.s as doesn't meet FACTOR_CMP
|
|
|
|
|
assert_eq!(a.clone() / b.clone(), DynNum::parse("0.18")); // Meets FACTOR_CMP so compare only 2 d.p.s
|
|
|
|
|
assert_eq!(b.clone() % a.clone(), DynNum::parse("61.65")); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::NativeFloat64); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
assert_eq!(a.clone() + b.clone(), DynNum { float64: NativeFloat64::from(123.45_f64 + 678.90_f64) }); |
|
|
|
|
assert_eq!(a.clone() - b.clone(), DynNum { float64: NativeFloat64::from(123.45_f64 - 678.90_f64) }); |
|
|
|
|
assert_eq!(a.clone() * b.clone(), DynNum { float64: NativeFloat64::from(123.45_f64 * 678.90_f64) }); |
|
|
|
|
assert_eq!(a.clone() / b.clone(), DynNum { float64: NativeFloat64::from(123.45_f64 / 678.90_f64) }); |
|
|
|
|
assert_eq!(b.clone() % a.clone(), DynNum { float64: NativeFloat64::from(678.90_f64 % 123.45_f64) }); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Rational); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
assert_eq!(a.clone() + b.clone(), DynNum::parse("802.35")); |
|
|
|
|
assert_eq!(a.clone() - b.clone(), DynNum::parse("-555.45")); |
|
|
|
|
assert_eq!(a.clone() * b.clone(), DynNum::parse("83810.205")); |
|
|
|
|
assert_eq!((a.clone() / b.clone()) * b.clone(), a); |
|
|
|
|
assert_eq!(b.clone() % a.clone(), DynNum::parse("61.65")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl ops::Add<&Self> for DynNum { |
|
|
|
|
type Output = Self; |
|
|
|
|
fn add(self, rhs: &Self) -> Self::Output { impl_1other_wrap!(self, rhs, add) } |
|
|
|
@ -420,6 +594,52 @@ impl ops::Rem<&Self> for DynNum { |
|
|
|
|
fn rem(self, rhs: &Self) -> Self::Output { impl_1other_wrap!(self, rhs, rem) } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn arith_owned_ref() { |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Fixed); |
|
|
|
|
Fixed::set_dps(2); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
assert_eq!(a.clone() + &b, DynNum::parse("802.35")); |
|
|
|
|
assert_eq!(a.clone() - &b, DynNum::parse("-555.45")); |
|
|
|
|
assert_eq!(a.clone() * &b, DynNum::parse("83810.20")); |
|
|
|
|
assert_eq!(a.clone() / &b, DynNum::parse("0.18")); |
|
|
|
|
assert_eq!(b.clone() % &a, DynNum::parse("61.65")); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::GuardedFixed); |
|
|
|
|
GuardedFixed::set_dps(2); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
assert_eq!(a.clone() + &b, DynNum::parse("802.35")); |
|
|
|
|
assert_eq!(a.clone() - &b, DynNum::parse("-555.45")); |
|
|
|
|
assert_eq!(a.clone() * &b, DynNum::parse("83810.205")); |
|
|
|
|
assert_eq!(a.clone() / &b, DynNum::parse("0.18")); |
|
|
|
|
assert_eq!(b.clone() % &a, DynNum::parse("61.65")); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::NativeFloat64); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
assert_eq!(a.clone() + &b, DynNum { float64: NativeFloat64::from(123.45_f64 + 678.90_f64) }); |
|
|
|
|
assert_eq!(a.clone() - &b, DynNum { float64: NativeFloat64::from(123.45_f64 - 678.90_f64) }); |
|
|
|
|
assert_eq!(a.clone() * &b, DynNum { float64: NativeFloat64::from(123.45_f64 * 678.90_f64) }); |
|
|
|
|
assert_eq!(a.clone() / &b, DynNum { float64: NativeFloat64::from(123.45_f64 / 678.90_f64) }); |
|
|
|
|
assert_eq!(b.clone() % &a, DynNum { float64: NativeFloat64::from(678.90_f64 % 123.45_f64) }); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Rational); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
assert_eq!(a.clone() + &b, DynNum::parse("802.35")); |
|
|
|
|
assert_eq!(a.clone() - &b, DynNum::parse("-555.45")); |
|
|
|
|
assert_eq!(a.clone() * &b, DynNum::parse("83810.205")); |
|
|
|
|
assert_eq!((a.clone() / &b) * &b, a); |
|
|
|
|
assert_eq!(b.clone() % &a, DynNum::parse("61.65")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl ops::AddAssign for DynNum { |
|
|
|
|
fn add_assign(&mut self, rhs: Self) { impl_1other_nowrap_mut!(self, rhs, add_assign) } |
|
|
|
|
} |
|
|
|
@ -440,6 +660,52 @@ impl ops::RemAssign for DynNum { |
|
|
|
|
fn rem_assign(&mut self, rhs: Self) { impl_1other_nowrap_mut!(self, rhs, rem_assign) } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn arithassign_owned() { |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Fixed); |
|
|
|
|
Fixed::set_dps(2); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
let mut x = a.clone(); x += b.clone(); assert_eq!(x, DynNum::parse("802.35")); |
|
|
|
|
let mut x = a.clone(); x -= b.clone(); assert_eq!(x, DynNum::parse("-555.45")); |
|
|
|
|
let mut x = a.clone(); x *= b.clone(); assert_eq!(x, DynNum::parse("83810.20")); |
|
|
|
|
let mut x = a.clone(); x /= b.clone(); assert_eq!(x, DynNum::parse("0.18")); |
|
|
|
|
let mut x = b.clone(); x %= a.clone(); assert_eq!(x, DynNum::parse("61.65")); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::GuardedFixed); |
|
|
|
|
GuardedFixed::set_dps(2); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
let mut x = a.clone(); x += b.clone(); assert_eq!(x, DynNum::parse("802.35")); |
|
|
|
|
let mut x = a.clone(); x -= b.clone(); assert_eq!(x, DynNum::parse("-555.45")); |
|
|
|
|
let mut x = a.clone(); x *= b.clone(); assert_eq!(x, DynNum::parse("83810.205")); |
|
|
|
|
let mut x = a.clone(); x /= b.clone(); assert_eq!(x, DynNum::parse("0.18")); |
|
|
|
|
let mut x = b.clone(); x %= a.clone(); assert_eq!(x, DynNum::parse("61.65")); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::NativeFloat64); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
let mut x = a.clone(); x += b.clone(); assert_eq!(x, DynNum { float64: NativeFloat64::from(123.45_f64 + 678.90_f64) }); |
|
|
|
|
let mut x = a.clone(); x -= b.clone(); assert_eq!(x, DynNum { float64: NativeFloat64::from(123.45_f64 - 678.90_f64) }); |
|
|
|
|
let mut x = a.clone(); x *= b.clone(); assert_eq!(x, DynNum { float64: NativeFloat64::from(123.45_f64 * 678.90_f64) }); |
|
|
|
|
let mut x = a.clone(); x /= b.clone(); assert_eq!(x, DynNum { float64: NativeFloat64::from(123.45_f64 / 678.90_f64) }); |
|
|
|
|
let mut x = b.clone(); x %= a.clone(); assert_eq!(x, DynNum { float64: NativeFloat64::from(678.90_f64 % 123.45_f64) }); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Rational); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
let mut x = a.clone(); x += b.clone(); assert_eq!(x, DynNum::parse("802.35")); |
|
|
|
|
let mut x = a.clone(); x -= b.clone(); assert_eq!(x, DynNum::parse("-555.45")); |
|
|
|
|
let mut x = a.clone(); x *= b.clone(); assert_eq!(x, DynNum::parse("83810.205")); |
|
|
|
|
let mut x = a.clone(); x /= b.clone(); x *= &b; assert_eq!(x, a); |
|
|
|
|
let mut x = b.clone(); x %= a.clone(); assert_eq!(x, DynNum::parse("61.65")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl ops::AddAssign<&Self> for DynNum { |
|
|
|
|
fn add_assign(&mut self, rhs: &Self) { impl_1other_nowrap_mut!(self, rhs, add_assign) } |
|
|
|
|
} |
|
|
|
@ -460,6 +726,52 @@ impl ops::RemAssign<&Self> for DynNum { |
|
|
|
|
fn rem_assign(&mut self, rhs: &Self) { impl_1other_nowrap_mut!(self, rhs, rem_assign) } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn arithassign_ref() { |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Fixed); |
|
|
|
|
Fixed::set_dps(2); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
let mut x = a.clone(); x += &b; assert_eq!(x, DynNum::parse("802.35")); |
|
|
|
|
let mut x = a.clone(); x -= &b; assert_eq!(x, DynNum::parse("-555.45")); |
|
|
|
|
let mut x = a.clone(); x *= &b; assert_eq!(x, DynNum::parse("83810.20")); |
|
|
|
|
let mut x = a.clone(); x /= &b; assert_eq!(x, DynNum::parse("0.18")); |
|
|
|
|
let mut x = b.clone(); x %= &a; assert_eq!(x, DynNum::parse("61.65")); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::GuardedFixed); |
|
|
|
|
GuardedFixed::set_dps(2); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
let mut x = a.clone(); x += &b; assert_eq!(x, DynNum::parse("802.35")); |
|
|
|
|
let mut x = a.clone(); x -= &b; assert_eq!(x, DynNum::parse("-555.45")); |
|
|
|
|
let mut x = a.clone(); x *= &b; assert_eq!(x, DynNum::parse("83810.205")); |
|
|
|
|
let mut x = a.clone(); x /= &b; assert_eq!(x, DynNum::parse("0.18")); |
|
|
|
|
let mut x = b.clone(); x %= &a; assert_eq!(x, DynNum::parse("61.65")); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::NativeFloat64); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
let mut x = a.clone(); x += &b; assert_eq!(x, DynNum { float64: NativeFloat64::from(123.45_f64 + 678.90_f64) }); |
|
|
|
|
let mut x = a.clone(); x -= &b; assert_eq!(x, DynNum { float64: NativeFloat64::from(123.45_f64 - 678.90_f64) }); |
|
|
|
|
let mut x = a.clone(); x *= &b; assert_eq!(x, DynNum { float64: NativeFloat64::from(123.45_f64 * 678.90_f64) }); |
|
|
|
|
let mut x = a.clone(); x /= &b; assert_eq!(x, DynNum { float64: NativeFloat64::from(123.45_f64 / 678.90_f64) }); |
|
|
|
|
let mut x = b.clone(); x %= &a; assert_eq!(x, DynNum { float64: NativeFloat64::from(678.90_f64 % 123.45_f64) }); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Rational); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
let mut x = a.clone(); x += &b; assert_eq!(x, DynNum::parse("802.35")); |
|
|
|
|
let mut x = a.clone(); x -= &b; assert_eq!(x, DynNum::parse("-555.45")); |
|
|
|
|
let mut x = a.clone(); x *= &b; assert_eq!(x, DynNum::parse("83810.205")); |
|
|
|
|
let mut x = a.clone(); x /= &b; x *= &b; assert_eq!(x, a); |
|
|
|
|
let mut x = b.clone(); x %= &a; assert_eq!(x, DynNum::parse("61.65")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
impl ops::Neg for &DynNum { |
|
|
|
|
type Output = DynNum; |
|
|
|
|
fn neg(self) -> Self::Output { impl_0arg_wrap!(self, neg) } |
|
|
|
@ -490,6 +802,52 @@ impl ops::Rem<Self> for &DynNum { |
|
|
|
|
fn rem(self, rhs: Self) -> Self::Output { impl_1other_wrap!(self, rhs, rem) } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
|
fn arith_ref_ref() { |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Fixed); |
|
|
|
|
Fixed::set_dps(2); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
assert_eq!(&a + &b, DynNum::parse("802.35")); |
|
|
|
|
assert_eq!(&a - &b, DynNum::parse("-555.45")); |
|
|
|
|
assert_eq!(&a * &b, DynNum::parse("83810.20")); |
|
|
|
|
assert_eq!(&a / &b, DynNum::parse("0.18")); |
|
|
|
|
assert_eq!(&b % &a, DynNum::parse("61.65")); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::GuardedFixed); |
|
|
|
|
GuardedFixed::set_dps(2); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
assert_eq!(&a + &b, DynNum::parse("802.35")); |
|
|
|
|
assert_eq!(&a - &b, DynNum::parse("-555.45")); |
|
|
|
|
assert_eq!(&a * &b, DynNum::parse("83810.205")); |
|
|
|
|
assert_eq!(&a / &b, DynNum::parse("0.18")); |
|
|
|
|
assert_eq!(&b % &a, DynNum::parse("61.65")); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::NativeFloat64); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
assert_eq!(&a + &b, DynNum { float64: NativeFloat64::from(123.45_f64 + 678.90_f64) }); |
|
|
|
|
assert_eq!(&a - &b, DynNum { float64: NativeFloat64::from(123.45_f64 - 678.90_f64) }); |
|
|
|
|
assert_eq!(&a * &b, DynNum { float64: NativeFloat64::from(123.45_f64 * 678.90_f64) }); |
|
|
|
|
assert_eq!(&a / &b, DynNum { float64: NativeFloat64::from(123.45_f64 / 678.90_f64) }); |
|
|
|
|
assert_eq!(&b % &a, DynNum { float64: NativeFloat64::from(678.90_f64 % 123.45_f64) }); |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
DynNum::set_kind(NumKind::Rational); |
|
|
|
|
let a = DynNum::parse("123.45"); |
|
|
|
|
let b = DynNum::parse("678.90"); |
|
|
|
|
assert_eq!(&a + &b, DynNum::parse("802.35")); |
|
|
|
|
assert_eq!(&a - &b, DynNum::parse("-555.45")); |
|
|
|
|
assert_eq!(&a * &b, DynNum::parse("83810.205")); |
|
|
|
|
assert_eq!((&a / &b) * &b, a); |
|
|
|
|
assert_eq!(&b % &a, DynNum::parse("61.65")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
impl ops::Add<&&Rational> for &Rational { |
|
|
|
|
|
|
|
|
|