use uninum::Number;
#[test]
fn test_basic_division() {
assert_eq!(
Number::from(30u64) / Number::from(3u64),
Number::from(10u64)
);
assert_eq!(
Number::from(-30i64) / Number::from(3i64),
Number::from(-10i64)
);
assert_eq!(
Number::from(-30i64) / Number::from(-3i64),
Number::from(10i64)
);
assert_eq!(Number::from(10.5) / Number::from(2.5), Number::from(4.2));
assert_eq!(Number::from(10u64) / Number::from(4.0), Number::from(2.5));
}
#[test]
fn test_exact_vs_inexact_division() {
assert_eq!(Number::from(10u64) / Number::from(2u64), Number::from(5u64));
assert_eq!(
Number::from(-20i64) / Number::from(4i64),
Number::from(-5i64)
);
let result = Number::from(10u64) / Number::from(3u64);
assert!(result.try_get_u64().is_none());
if let Some(f) = result.try_get_f64() {
assert!((f - 3.333333).abs() < 0.000001);
}
#[cfg(feature = "decimal")]
{
if let Some(d) = result.try_get_decimal() {
assert!(d.to_string().starts_with("3.333"));
}
}
}
#[test]
fn test_division_by_zero() {
let result = Number::from(42) / Number::from(0);
assert!(result.is_pos_inf());
let result = Number::from(-42) / Number::from(0);
assert!(result.is_neg_inf());
let result = Number::from(0) / Number::from(0);
assert!(result.is_nan());
let result = Number::from(1.0) / Number::from(0.0);
assert!(result.is_pos_inf());
}
#[test]
fn test_primitive_operations() {
let num = Number::from(20);
assert_eq!(&num / 4, Number::from(5));
assert_eq!(100 / &num, Number::from(5));
assert_eq!(&num / 2.5, Number::from(8.0));
}
#[test]
fn test_identity_operations() {
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)
);
assert_eq!(Number::from(42) / Number::from(42), Number::from(1));
assert_eq!(Number::from(-42) / Number::from(-42), Number::from(1));
}
#[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!((neg_inf.clone() / normal.clone()).is_neg_inf());
let result = normal.clone() / inf.clone();
if let Some(f) = result.try_get_f64() {
assert_eq!(f, 0.0);
}
assert!((inf.clone() / inf.clone()).is_nan());
assert!((inf / neg_inf).is_nan());
assert!((nan.clone() / normal.clone()).is_nan());
assert!((normal / nan).is_nan());
}
#[cfg(feature = "decimal")]
#[test]
fn test_decimal_precision() {
use rust_decimal::Decimal;
let a = Number::from(Decimal::new(1000, 2)); let b = Number::from(Decimal::new(400, 2));
let quotient = a / b;
if let Some(d) = quotient.try_get_decimal() {
assert_eq!(d.to_string(), "2.50");
}
let precise1 = Number::from(Decimal::new(10000, 4)); let precise2 = Number::from(Decimal::new(30000, 4)); let quotient = precise1 / precise2;
if let Some(d) = quotient.try_get_decimal() {
assert!(d.to_string().starts_with("0.3333"));
}
}
#[test]
fn test_float_integer_paths() {
let exact = Number::from(8.0) / Number::from(4.0);
assert!(matches!(exact, Number::F64(_)));
assert_eq!(exact.try_get_f64().unwrap(), 2.0);
let inexact = Number::from(10.0) / Number::from(3.0);
#[cfg(feature = "decimal")]
{
use rust_decimal::Decimal;
use std::convert::TryFrom;
let as_decimal = inexact
.try_get_decimal()
.expect("expected Decimal fallback");
let expected = Decimal::try_from(10.0).unwrap() / Decimal::try_from(3.0).unwrap();
assert_eq!(as_decimal.to_string(), expected.to_string());
}
#[cfg(not(feature = "decimal"))]
{
let as_f64 = inexact.try_get_f64().unwrap();
assert!((as_f64 - 3.3333333333333335).abs() < 1e-12);
}
}
#[cfg(feature = "decimal")]
#[test]
fn test_decimal_division_by_zero_paths() {
use rust_decimal::Decimal;
let zero = Number::from(Decimal::new(0, 0));
let positive = Number::from(Decimal::new(123, 2)); let negative = Number::from(Decimal::new(-456, 2));
assert!(matches!(zero.clone() / zero.clone(), Number::F64(ref f) if f.0.is_nan()));
assert!(
matches!(positive / zero.clone(), Number::F64(ref f) if f.0.is_sign_positive() && f.0.is_infinite())
);
assert!(
matches!(negative / zero, Number::F64(ref f) if f.0.is_sign_negative() && f.0.is_infinite())
);
}
#[cfg(feature = "decimal")]
#[test]
fn test_decimal_checked_div_overflow_falls_back_to_f64() {
use rust_decimal::Decimal;
let near_max = Number::from(Decimal::MAX);
let tiny = Number::from(Decimal::new(1, 28));
let result = near_max / tiny;
assert!(
result.try_get_decimal().is_none(),
"expected Decimal::checked_div overflow to fall back to F64"
);
assert!(
result.try_get_f64().is_some(),
"division overflow should produce a lossy F64"
);
}
#[cfg(feature = "decimal")]
#[test]
fn test_float_division_decimal_conversion_failure_falls_back() {
let large_integral = Number::from(1e29);
let divisor = Number::from(3.0);
let result = large_integral / divisor;
assert!(
result.try_get_decimal().is_none(),
"values beyond Decimal::MAX should not produce Decimal results"
);
assert!(
result.try_get_f64().is_some(),
"conversion failure should fall back to F64"
);
}
#[test]
fn test_reciprocal() {
assert_eq!(Number::from(1) / Number::from(2), Number::from(0.5));
assert_eq!(Number::from(1) / Number::from(4), Number::from(0.25));
let n = Number::from(5);
let reciprocal = Number::from(1) / n.clone();
let double_reciprocal = Number::from(1) / reciprocal;
if let Some(f) = double_reciprocal.try_get_f64() {
assert!((f - 5.0).abs() < 1e-10);
}
}
#[test]
fn test_chain_operations() {
let result = Number::from(100) / Number::from(5) / Number::from(4);
assert_eq!(result, Number::from(5));
let result = Number::from(100) / Number::from(3) / Number::from(2);
if let Some(f) = result.try_get_f64() {
assert!((f - 16.666666).abs() < 0.000001);
}
}
#[test]
fn test_extreme_values() {
let large = Number::from(1e308);
let small = Number::from(1e-308);
let result = large / small;
assert!(result.is_pos_inf());
let small = Number::from(1e-308);
let large = Number::from(1e308);
let result = small / large;
if let Some(f) = result.try_get_f64() {
assert_eq!(f, 0.0); }
let a = Number::from(1.0);
let b = Number::from(1.0 + f64::EPSILON);
let result = a / b;
if let Some(f) = result.try_get_f64() {
assert!((f - (1.0 / (1.0 + f64::EPSILON))).abs() < 1e-15);
}
}