✨ Percentage
This commit is contained in:
		| @@ -151,6 +151,17 @@ class AddExpr extends Expr { | ||||
|       return IntExpr(l.value + r.value); | ||||
|     } | ||||
|  | ||||
|     // 小数相加 | ||||
|     if (l is DoubleExpr && r is DoubleExpr) { | ||||
|       return DoubleExpr(l.value + r.value); | ||||
|     } | ||||
|     if (l is IntExpr && r is DoubleExpr) { | ||||
|       return DoubleExpr(l.value + r.value); | ||||
|     } | ||||
|     if (l is DoubleExpr && r is IntExpr) { | ||||
|       return DoubleExpr(l.value + r.value); | ||||
|     } | ||||
|  | ||||
|     // 分数相加 / 分数与整数相加 | ||||
|     if (l is FractionExpr && r is FractionExpr) { | ||||
|       return FractionExpr( | ||||
| @@ -171,6 +182,14 @@ class AddExpr extends Expr { | ||||
|       ).simplify(); | ||||
|     } | ||||
|  | ||||
|     // 分数与小数相加 | ||||
|     if (l is FractionExpr && r is DoubleExpr) { | ||||
|       return DoubleExpr(l.numerator / l.denominator + r.value); | ||||
|     } | ||||
|     if (l is DoubleExpr && r is FractionExpr) { | ||||
|       return DoubleExpr(l.value + r.numerator / r.denominator); | ||||
|     } | ||||
|  | ||||
|     // 合并同类的 sqrt 项: a*sqrt(X) + b*sqrt(X) = (a+b)*sqrt(X) | ||||
|     var a = _asSqrtTerm(l); | ||||
|     var b = _asSqrtTerm(r); | ||||
| @@ -221,6 +240,18 @@ class SubExpr extends Expr { | ||||
|     if (l is IntExpr && r is IntExpr) { | ||||
|       return IntExpr(l.value - r.value); | ||||
|     } | ||||
|  | ||||
|     // 小数相减 | ||||
|     if (l is DoubleExpr && r is DoubleExpr) { | ||||
|       return DoubleExpr(l.value - r.value); | ||||
|     } | ||||
|     if (l is IntExpr && r is DoubleExpr) { | ||||
|       return DoubleExpr(l.value - r.value); | ||||
|     } | ||||
|     if (l is DoubleExpr && r is IntExpr) { | ||||
|       return DoubleExpr(l.value - r.value); | ||||
|     } | ||||
|  | ||||
|     if (l is FractionExpr && r is FractionExpr) { | ||||
|       return FractionExpr( | ||||
|         l.numerator * r.denominator - r.numerator * l.denominator, | ||||
| @@ -240,6 +271,14 @@ class SubExpr extends Expr { | ||||
|       ).simplify(); | ||||
|     } | ||||
|  | ||||
|     // 分数与小数相减 | ||||
|     if (l is FractionExpr && r is DoubleExpr) { | ||||
|       return DoubleExpr(l.numerator / l.denominator - r.value); | ||||
|     } | ||||
|     if (l is DoubleExpr && r is FractionExpr) { | ||||
|       return DoubleExpr(l.value - r.numerator / r.denominator); | ||||
|     } | ||||
|  | ||||
|     // 处理同类 sqrt 项: a*sqrt(X) - b*sqrt(X) = (a-b)*sqrt(X) | ||||
|     var a = _asSqrtTerm(l); | ||||
|     var b = _asSqrtTerm(r); | ||||
| @@ -311,6 +350,18 @@ class MulExpr extends Expr { | ||||
|     if (l is IntExpr && r is IntExpr) { | ||||
|       return IntExpr(l.value * r.value); | ||||
|     } | ||||
|  | ||||
|     // 小数相乘 | ||||
|     if (l is DoubleExpr && r is DoubleExpr) { | ||||
|       return DoubleExpr(l.value * r.value); | ||||
|     } | ||||
|     if (l is IntExpr && r is DoubleExpr) { | ||||
|       return DoubleExpr(l.value * r.value); | ||||
|     } | ||||
|     if (l is DoubleExpr && r is IntExpr) { | ||||
|       return DoubleExpr(l.value * r.value); | ||||
|     } | ||||
|  | ||||
|     if (l is FractionExpr && r is IntExpr) { | ||||
|       return FractionExpr(l.numerator * r.value, l.denominator).simplify(); | ||||
|     } | ||||
| @@ -324,6 +375,14 @@ class MulExpr extends Expr { | ||||
|       ).simplify(); | ||||
|     } | ||||
|  | ||||
|     // 分数与小数相乘 | ||||
|     if (l is FractionExpr && r is DoubleExpr) { | ||||
|       return DoubleExpr(l.numerator / l.denominator * r.value); | ||||
|     } | ||||
|     if (l is DoubleExpr && r is FractionExpr) { | ||||
|       return DoubleExpr(l.value * r.numerator / r.denominator); | ||||
|     } | ||||
|  | ||||
|     // sqrt * sqrt: sqrt(a)*sqrt(a) = a | ||||
|     if (l is SqrtExpr && | ||||
|         r is SqrtExpr && | ||||
| @@ -856,6 +915,37 @@ class AbsExpr extends Expr { | ||||
|   String toString() => "|$inner|"; | ||||
| } | ||||
|  | ||||
| // === PercentExpr === | ||||
| class PercentExpr extends Expr { | ||||
|   final Expr inner; | ||||
|   PercentExpr(this.inner); | ||||
|  | ||||
|   @override | ||||
|   Expr simplify() => PercentExpr(inner.simplify()); | ||||
|  | ||||
|   @override | ||||
|   Expr evaluate() { | ||||
|     var i = inner.evaluate(); | ||||
|     if (i is IntExpr) { | ||||
|       return DoubleExpr(i.value / 100.0); | ||||
|     } | ||||
|     if (i is DoubleExpr) { | ||||
|       return DoubleExpr(i.value / 100.0); | ||||
|     } | ||||
|     if (i is FractionExpr) { | ||||
|       return DoubleExpr(i.numerator / (i.denominator * 100.0)); | ||||
|     } | ||||
|     return PercentExpr(i); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Expr substitute(String varName, Expr value) => | ||||
|       PercentExpr(inner.substitute(varName, value)); | ||||
|  | ||||
|   @override | ||||
|   String toString() => "$inner%"; | ||||
| } | ||||
|  | ||||
| // === 辅助:识别 a * sqrt(X) 形式 === | ||||
| class _SqrtTerm { | ||||
|   final int coef; | ||||
|   | ||||
| @@ -17,7 +17,15 @@ class Parser { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   Expr parse() => parseAdd(); | ||||
|   Expr parse() { | ||||
|     var expr = parseAdd(); | ||||
|     skipSpaces(); | ||||
|     if (!isEnd && current == '%') { | ||||
|       eat(); | ||||
|       expr = PercentExpr(expr); | ||||
|     } | ||||
|     return expr; | ||||
|   } | ||||
|  | ||||
|   Expr parseAdd() { | ||||
|     var expr = parseMul(); | ||||
| @@ -46,6 +54,12 @@ class Parser { | ||||
|       } | ||||
|       skipSpaces(); | ||||
|     } | ||||
|     // Handle percentage operator | ||||
|     skipSpaces(); | ||||
|     if (!isEnd && current == '%') { | ||||
|       eat(); | ||||
|       expr = PercentExpr(expr); | ||||
|     } | ||||
|     return expr; | ||||
|   } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user