use uninum::Number;
#[test]
fn test_basic_subtraction() {
assert_eq!(
Number::from(30u64) - Number::from(10u64),
Number::from(20u64)
);
assert_eq!(
Number::from(20i64) - Number::from(30i64),
Number::from(-10i64)
);
assert_eq!(Number::from(10.5) - Number::from(2.5), Number::from(8.0));
assert_eq!(Number::from(10u64) - Number::from(2.5), Number::from(7.5));
}
#[test]
fn test_unsigned_underflow() {
let result = Number::from(5u64) - Number::from(10u64);
assert_eq!(result, Number::from(-5i64));
assert_eq!(Number::from(0u64) - Number::from(1u64), Number::from(-1i64));
let result = Number::from(1000u64) - Number::from(2000u64);
assert!(result.try_get_u64().is_none()); #[cfg(feature = "decimal")]
assert!(result.try_get_i64() == Some(-1000) || result.try_get_decimal().is_some());
#[cfg(not(feature = "decimal"))]
{
if let Some(i) = result.try_get_i64() {
assert_eq!(i, -1000);
} else if let Some(f) = result.try_get_f64() {
assert_eq!(f, -1000.0);
} else {
panic!("Unexpected result type: {result:?}");
}
}
}
#[test]
fn test_signed_overflow() {
let result = Number::from(i64::MIN) - Number::from(1i64);
assert!(result.try_get_i64().is_none()); assert!(result.is_finite());
let result = Number::from(i64::MAX) - Number::from(i64::MIN);
assert!(result.try_get_i64().is_none()); }
#[test]
fn test_primitive_operations() {
let num = Number::from(20);
assert_eq!(&num - 5, Number::from(15));
assert_eq!(30 - &num, Number::from(10));
assert_eq!(&num - 5.5, Number::from(14.5));
}
#[test]
fn test_zero_operations() {
assert_eq!(
Number::from(42u64) - Number::from(0u64),
Number::from(42u64)
);
assert_eq!(
Number::from(-42i64) - Number::from(0i64),
Number::from(-42i64)
);
assert_eq!(Number::from(3.16) - Number::from(0.0), Number::from(3.16));
assert_eq!(Number::from(0u64) - Number::from(0u64), Number::from(0u64));
assert_eq!(
Number::from(100u64) - Number::from(100u64),
Number::from(0u64)
);
}
#[test]
fn test_chain_operations() {
let result = Number::from(100u64) - Number::from(50u64) - Number::from(60u64);
assert_eq!(result, Number::from(-10i64));
let result = Number::from(1000) - Number::from(100) - Number::from(200) - Number::from(300);
assert_eq!(result, Number::from(400));
}
#[test]
fn test_special_float_values() {
let inf = Number::from(f64::INFINITY);
let neg_inf = Number::from(f64::NEG_INFINITY);
let nan = Number::from(f64::NAN);
let normal = Number::from(42);
assert!((inf.clone() - normal.clone()).is_pos_inf());
assert!((normal.clone() - inf.clone()).is_neg_inf());
assert!((nan.clone() - normal.clone()).is_nan());
assert!((normal - nan).is_nan());
assert!((inf.clone() - inf).is_nan());
assert!((neg_inf.clone() - neg_inf).is_nan());
}
#[cfg(feature = "decimal")]
#[test]
fn test_decimal_precision() {
use rust_decimal::Decimal;
let a = Number::from(Decimal::new(1050, 2)); let b = Number::from(Decimal::new(250, 2));
let diff = a - b;
if let Some(d) = diff.try_get_decimal() {
assert_eq!(d.to_string(), "8.00");
}
let precise1 = Number::from(Decimal::new(54321, 4)); let precise2 = Number::from(Decimal::new(12345, 4)); let diff = precise1 - precise2;
if let Some(d) = diff.try_get_decimal() {
assert_eq!(d.to_string(), "4.1976");
}
}
#[test]
fn test_mathematical_properties() {
let a = Number::from(100);
let b = Number::from(30);
let c = Number::from(20);
assert_ne!(a.clone() - b.clone(), b.clone() - a.clone());
assert_ne!(
(a.clone() - b.clone()) - c.clone(),
a.clone() - (b.clone() - c.clone())
);
assert_eq!(a.clone() - b.clone() - c.clone(), a.clone() - (b + c));
}
#[test]
fn test_extreme_values() {
let a = Number::from(1.0000000000001);
let b = Number::from(1.0);
let diff = a - b;
if let Some(f) = diff.try_get_f64() {
assert!((f - 0.0000000000001).abs() < 1e-15);
}
let large = Number::from(1e308);
let small = Number::from(1e-308);
let diff = large - small;
if let Some(f) = diff.try_get_f64() {
assert_eq!(f, 1e308); }
}