如何强制表达式求值为double 解决Flee库整数除法错误
强制Flee库表达式无double字面量时按double类型求值方案
问题核心原因
Flee默认对齐C#语言类型推断规则:当表达式内所有操作数均为整数字面量时,运算会按整数类型规则执行,整数除法直接截断小数部分返回整数结果,因此4/3会返回1,仅当表达式中存在double类型字面量时,才会触发类型提升按浮点规则运算。
可行实现方案
配置上下文全局整数解析规则
直接修改Flee表达式上下文的类型配置,强制所有整数字面量默认解析为double类型,无需修改任何表达式文本,是最简洁的方案:using Flee.PublicTypes; // 初始化表达式计算上下文 ExpressionContext context = new ExpressionContext(); // 强制整数字面量默认类型为double context.Options.IntegerDataType = typeof(double); // 强制浮点字面量默认类型为double context.Options.RealLiteralDataType = typeof(double); // 直接计算未带double字面量的表达式 var expression = context.CompileDynamic("4/3"); double calcResult = (double)expression.Evaluate(); // 计算结果为1.333333...,不会返回整数1表达式预处理自动转换字面量
若无法修改上下文全局配置,可在表达式传入Flee前做文本预处理,自动为所有整数字面量追加double类型标记,触发浮点运算:using System.Text.RegularExpressions; public string ConvertExprToDoubleCalc(string rawExpression) { // 匹配独立整数字面量,排除已带小数点、属于变量名/函数名组成部分的数字 return Regex.Replace(rawExpression, @"(?<![\.\w])(\d+)(?![\.\w])", "$1.0"); } // 调用示例 string processedExpr = ConvertExprToDoubleCalc("(4/3) * 5 + 7"); // 处理后表达式为(4.0/3.0) * 5.0 + 7.0,传入Flee后自动按double规则运算自定义运算符重写整数除法逻辑
若仅需要修正除法运算的整数截断问题,不需要所有整数运算都按double执行,可单独为整数除法注册自定义运算逻辑:// 注册int类型除法的自定义实现,强制返回double结果 context.Operators.AddOperator<int, int, double>("/", (left, right) => (double)left / right);
注意:整数除法返回截断后的整数是C#语言规范明确约定的默认行为,Flee的默认逻辑是对齐语言规范,所有调整都应在Flee库的配置/扩展层面实现,不要尝试修改CLR全局的类型运算规则。
内容的提问来源于stack exchange,提问作者yy uu
相关产品推荐
相关产品推荐

