use objects::{ArithmeticOp, CompareOp, EndorNumber, EndorReal}; fn equal(a: &EndorNumber, b: &EndorNumber) { assert!(a.numeric_compare(b, CompareOp::Eq).unwrap()); } #[test] fn exact_real_arithmetic_keeps_large_values_and_cross_representation_equivalence() { let tenth = EndorNumber::decimal("0.10").unwrap(); let fifth = EndorNumber::rational("2", "10").unwrap(); equal( &tenth.arithmetic(&fifth, ArithmeticOp::Add).unwrap(), &EndorNumber::decimal("0.3").unwrap(), ); let large = EndorNumber::integer("9223372036854775807").unwrap(); equal( &large.arithmetic(&1_i64.into(), ArithmeticOp::Add).unwrap(), &EndorNumber::integer("9223372036854775808").unwrap(), ); let min = EndorNumber::integer("-9223372036854775808").unwrap(); assert_eq!(min.as_i64(), Some(i64::MIN)); equal( &min.negated().unwrap(), &EndorNumber::integer("9223372036854775808").unwrap(), ); equal( &EndorNumber::rational("2", "6").unwrap(), &EndorNumber::rational("1", "3").unwrap(), ); assert!( EndorNumber::integer("9007199254740993") .unwrap() .numeric_compare(&EndorNumber::binary_float(9007199254740992.), CompareOp::Gt) .unwrap() ); } #[test] fn ieee_signed_zero_nan_and_operation_limits_are_explicit() { let negative = EndorNumber::binary_float(0.).negated().unwrap(); assert_eq!( negative.as_real(), Some(&EndorReal::BinaryFloat((-0.0_f64).to_bits())) ); let nan = EndorNumber::binary_float(f64::NAN); assert!(!nan.numeric_compare(&nan, CompareOp::Eq).unwrap()); assert!(nan.numeric_compare(&nan, CompareOp::Ne).unwrap()); assert!( EndorNumber::from(1_i64) .arithmetic(&0_i64.into(), ArithmeticOp::Divide) .is_err() ); assert!( EndorNumber::binary_float(f64::MAX) .arithmetic(&2_i64.into(), ArithmeticOp::Multiply) .is_err() ); let huge = EndorNumber::decimal("1e99999999999999999").unwrap(); assert_eq!(huge.to_string(), "1e99999999999999999"); assert!(huge.arithmetic(&1_i64.into(), ArithmeticOp::Add).is_err()); }