feat: execute source control flow and exact real arithmetic

This commit is contained in:
2026-11-12 10:48:27 +08:00
parent f3e1670c58
commit 5ff1c68f5f
28 changed files with 1045 additions and 117 deletions
+58
View File
@@ -0,0 +1,58 @@
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());
}