use uninum::Number;
#[test]
fn test_basic_multiplication() {
assert_eq!(
Number::from(10u64) * Number::from(3u64),
Number::from(30u64)
);
assert_eq!(
Number::from(-10i64) * Number::from(3i64),
Number::from(-30i64)
);
assert_eq!(
Number::from(-10i64) * Number::from(-3i64),
Number::from(30i64)
);
assert_eq!(Number::from(10.5) * Number::from(2.0), Number::from(21.0));
assert_eq!(Number::from(10u64) * Number::from(2.5), Number::from(25.0));
assert_eq!(
Number::from(-5i64) * Number::from(10u64),
Number::from(-50i64)
);
}
#[test]
fn test_overflow_handling() {
assert_eq!(
Number::from(1_000_000u64) * Number::from(1_000_000u64),
Number::from(1_000_000_000_000u64)
);
let result = Number::from(u64::MAX) * Number::from(2u64);
assert!(result.try_get_u64().is_none()); assert!(result.is_finite());
let result = Number::from(i64::MAX) * Number::from(2i64);
assert!(result.try_get_i64().is_none());
assert!(result.is_finite());
}
#[test]
fn test_primitive_operations() {
let num = Number::from(10);
assert_eq!(&num * 3, Number::from(30));
assert_eq!(3 * &num, Number::from(30));
assert_eq!(&num * 2.5, Number::from(25.0));
assert_eq!(&num * 0.5, Number::from(5.0));
}
#[test]
fn test_identity_and_zero() {
assert_eq!(Number::from(42u64) * Number::from(0u64), Number::from(0u64));
assert_eq!(
Number::from(-42i64) * Number::from(0i64),
Number::from(0i64)
);
assert_eq!(Number::from(42.5) * Number::from(0.0), Number::from(0.0));
assert_eq!(
Number::from(42u64) * Number::from(1u64),
Number::from(42u64)
);
assert_eq!(
Number::from(-42i64) * Number::from(1i64),
Number::from(-42i64)
);
assert_eq!(Number::from(42.5) * Number::from(1.0), Number::from(42.5));
assert_eq!(
Number::from(42i64) * Number::from(-1i64),
Number::from(-42i64)
);
assert_eq!(
Number::from(-42i64) * Number::from(-1i64),
Number::from(42i64)
);
}
#[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 zero = Number::from(0);
let normal = Number::from(42);
assert!((inf.clone() * normal.clone()).is_pos_inf());
assert!((neg_inf.clone() * normal.clone()).is_neg_inf());
assert!((inf.clone() * Number::from(-1)).is_neg_inf());
assert!((neg_inf.clone() * Number::from(-1)).is_pos_inf());
assert!((nan.clone() * normal.clone()).is_nan());
assert!((inf.clone() * zero.clone()).is_nan());
assert!((neg_inf * zero).is_nan());
}
#[test]
fn test_signed_zero() {
let pos_zero = Number::from(0.0);
let neg_zero = Number::from(-0.0);
let pos = Number::from(42.0);
let neg = Number::from(-42.0);
let result = pos.clone() * pos_zero.clone();
if let Some(f) = result.try_get_f64() {
assert!(f == 0.0 && f.is_sign_positive());
}
let result = pos * neg_zero.clone();
if let Some(f) = result.try_get_f64() {
assert!(f == 0.0 && f.is_sign_negative());
}
let result = neg * neg_zero;
if let Some(f) = result.try_get_f64() {
assert!(f == 0.0 && f.is_sign_positive());
}
}
#[cfg(feature = "decimal")]
#[test]
fn test_decimal_precision() {
use rust_decimal::Decimal;
let a = Number::from(Decimal::new(250, 2)); let b = Number::from(Decimal::new(400, 2));
let product = a * b;
if let Some(d) = product.try_get_decimal() {
assert_eq!(d.to_string(), "10.0000"); }
let small1 = Number::from(Decimal::new(123, 3)); let small2 = Number::from(Decimal::new(456, 3)); let product = small1 * small2;
if let Some(d) = product.try_get_decimal() {
assert_eq!(d.to_string(), "0.056088");
}
}
#[test]
fn test_mathematical_properties() {
let a = Number::from(2);
let b = Number::from(3);
let c = Number::from(4);
assert_eq!(a.clone() * b.clone(), b.clone() * a.clone());
assert_eq!(
(a.clone() * b.clone()) * c.clone(),
a.clone() * (b.clone() * c.clone())
);
assert_eq!(
a.clone() * (b.clone() + c.clone()),
a.clone() * b.clone() + a.clone() * c.clone()
);
}
#[test]
fn test_chain_operations() {
let result = Number::from(2) * Number::from(3) * Number::from(4);
assert_eq!(result, Number::from(24));
let result = Number::from(10u64) * Number::from(2.5) * Number::from(2u64);
assert_eq!(result, Number::from(50.0));
let result = Number::from(1000u64) * Number::from(1000u64) * Number::from(1000u64);
assert_eq!(result, Number::from(1_000_000_000u64));
}
#[test]
fn test_extreme_values() {
let tiny1 = Number::from(1e-150);
let tiny2 = Number::from(1e-150);
let product = tiny1 * tiny2;
if let Some(f) = product.try_get_f64() {
assert_eq!(f, 1e-300);
}
let large1 = Number::from(1e150);
let large2 = Number::from(1e150);
let product = large1 * large2;
if let Some(f) = product.try_get_f64() {
assert!((f - 1e300).abs() < 1e290 || f == 9.999999999999999e299);
}
let large = Number::from(1e308);
let small = Number::from(1e-308);
let product = large * small;
if let Some(f) = product.try_get_f64() {
assert!((f - 1.0).abs() < 0.1 || f == 0.9999999999999999);
}
}