From 8125ea2e3b1109bac51eea99b1f956a1af41be0d Mon Sep 17 00:00:00 2001 From: boris Date: Sun, 5 Jul 2026 03:00:34 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=A8Platform=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E9=99=A4=E6=B3=95=E6=95=B4=E6=95=B0=E9=87=8D=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fidc-core/src/platform_expr_strategy.rs | 89 ++++++++++++++++--- 1 file changed, 79 insertions(+), 10 deletions(-) diff --git a/crates/fidc-core/src/platform_expr_strategy.rs b/crates/fidc-core/src/platform_expr_strategy.rs index 457e932..8da186b 100644 --- a/crates/fidc-core/src/platform_expr_strategy.rs +++ b/crates/fidc-core/src/platform_expr_strategy.rs @@ -580,6 +580,18 @@ pub struct PlatformSelectionQuotePlan { pub diagnostics: Vec, } +fn platform_safe_div(lhs: f64, rhs: f64, fallback: f64) -> f64 { + if rhs.abs() <= f64::EPSILON { + fallback + } else { + lhs / rhs + } +} + +fn platform_safe_div_default(lhs: f64, rhs: f64) -> f64 { + platform_safe_div(lhs, rhs, 0.0) +} + impl PlatformExprStrategy { fn market_cap_storage_to_strategy_unit(value: f64) -> f64 { value @@ -608,18 +620,40 @@ impl PlatformExprStrategy { |value: f64, fallback: f64| if value.is_finite() { value } else { fallback }, ); engine.register_fn("safe_div", |lhs: f64, rhs: f64, fallback: f64| { - if rhs.abs() <= f64::EPSILON { - fallback - } else { - lhs / rhs - } + platform_safe_div(lhs, rhs, fallback) + }); + engine.register_fn("safe_div", |lhs: f64, rhs: i64, fallback: f64| { + platform_safe_div(lhs, rhs as f64, fallback) + }); + engine.register_fn("safe_div", |lhs: f64, rhs: f64, fallback: i64| { + platform_safe_div(lhs, rhs, fallback as f64) + }); + engine.register_fn("safe_div", |lhs: f64, rhs: i64, fallback: i64| { + platform_safe_div(lhs, rhs as f64, fallback as f64) + }); + engine.register_fn("safe_div", |lhs: i64, rhs: f64, fallback: f64| { + platform_safe_div(lhs as f64, rhs, fallback) + }); + engine.register_fn("safe_div", |lhs: i64, rhs: i64, fallback: f64| { + platform_safe_div(lhs as f64, rhs as f64, fallback) + }); + engine.register_fn("safe_div", |lhs: i64, rhs: f64, fallback: i64| { + platform_safe_div(lhs as f64, rhs, fallback as f64) + }); + engine.register_fn("safe_div", |lhs: i64, rhs: i64, fallback: i64| { + platform_safe_div(lhs as f64, rhs as f64, fallback as f64) }); engine.register_fn("safe_div", |lhs: f64, rhs: f64| { - if rhs.abs() <= f64::EPSILON { - 0.0 - } else { - lhs / rhs - } + platform_safe_div_default(lhs, rhs) + }); + engine.register_fn("safe_div", |lhs: f64, rhs: i64| { + platform_safe_div_default(lhs, rhs as f64) + }); + engine.register_fn("safe_div", |lhs: i64, rhs: f64| { + platform_safe_div_default(lhs as f64, rhs) + }); + engine.register_fn("safe_div", |lhs: i64, rhs: i64| { + platform_safe_div_default(lhs as f64, rhs as f64) }); engine.register_fn( "iff", @@ -8440,6 +8474,27 @@ mod tests { .expect("two-arg safe_div should evaluate"), 2.0 ); + assert_eq!( + strategy + .engine + .eval::("safe_div(6.0, 3)") + .expect("two-arg safe_div should accept integer rhs"), + 2.0 + ); + assert_eq!( + strategy + .engine + .eval::("safe_div(6, 3.0)") + .expect("two-arg safe_div should accept integer lhs"), + 2.0 + ); + assert_eq!( + strategy + .engine + .eval::("safe_div(6, 3)") + .expect("two-arg safe_div should accept integer literals"), + 2.0 + ); assert_eq!( strategy .engine @@ -8454,6 +8509,20 @@ mod tests { .expect("three-arg safe_div should preserve explicit fallback"), -1.0 ); + assert_eq!( + strategy + .engine + .eval::("safe_div(6.0, 0, -1)") + .expect("three-arg safe_div should accept integer rhs and fallback"), + -1.0 + ); + assert_eq!( + strategy + .engine + .eval::("safe_div(6, 0.0, -1)") + .expect("three-arg safe_div should accept integer lhs and fallback"), + -1.0 + ); } #[test]