diff --git a/docs_dev/plans/2026-07-31-shelf-c-attribute-shop.md b/docs_dev/plans/2026-07-31-shelf-c-attribute-shop.md index e152cca..83689c4 100644 --- a/docs_dev/plans/2026-07-31-shelf-c-attribute-shop.md +++ b/docs_dev/plans/2026-07-31-shelf-c-attribute-shop.md @@ -61,7 +61,7 @@ Expected: `Switched to a new branch 'feat/shelf-c-attribute-shop'` **Interfaces:** - Consumes: 无(零依赖) -- Produces: `PriceFormula.compute(spec: Dictionary, purchased: int) -> int`;`PriceFormula.curve_from_string(s: String) -> PriceFormula.Curve`;`enum PriceCurve { GEOMETRIC, LINEAR, FLAT }` +- Produces: `PriceFormula.compute(spec: Dictionary, purchased: int) -> int`;`PriceFormula.curve_from_string(s: String) -> PriceFormula.PriceCurve`;`enum PriceCurve { GEOMETRIC, LINEAR, FLAT }` > 纯函数,**先写断言、看它失败、再实现**。断言经 `execute_editor_script` 执行(项目无测试框架)。 diff --git a/scripts/domain/price_formula.gd b/scripts/domain/price_formula.gd index a7622a5..630fa3e 100644 --- a/scripts/domain/price_formula.gd +++ b/scripts/domain/price_formula.gd @@ -42,4 +42,14 @@ static func compute(spec: Dictionary, purchased: int) -> int: raw = base _: raw = base * pow(growth, float(n)) + # raw 可能在两个不同的地方失控:pow() 把 double 本身推到 INF(n 极大,如 geometric + # n≈5077+),或者 raw 仍是合法有限 double,但早已超出 int64 可安全表示的范围(如 + # geometric n=300 时 raw≈9.7e19——finite 但 > INT64_MAX≈9.22e18)。后者 is_finite() + # 测不出来,roundi() 对超范围 float 的行为是未定义/环绕,曾亲测把它环绕成极小/负值, + # 再经 maxi(...,1) 静默塌陷成 1——方向与"买得越多越贵"完全相反。故用同一个安全阈值 + # 9.0e15(远小于 INT64_MAX,远超任何合理金币量)同时兼答两种情况。 + const _PRICE_CLAMP: float = 9.0e15 + if not is_finite(raw) or raw > _PRICE_CLAMP: + push_error("PriceFormula: 价格溢出(base=%f growth=%f purchased=%d),已钳到上限" % [base, growth, n]) + raw = _PRICE_CLAMP return maxi(roundi(raw), 1)