[英]How to force c# binary int division to return a double?
如何强制加倍x = 3/2; 在没有D后缀或强制转换的情况下以x返回1.5? 是否有任何类型的操作员过载可以完成? 还是一些编译器选项?
令人惊讶的是,由于以下原因,添加强制转换或后缀并不是那么简单:
业务用户需要编写和调试自己的公式。 目前,C#正像DSL(领域特定语言)那样被使用,因为这些用户不是计算机科学工程师。 因此,他们所知道的就是如何编辑和创建几种类型的类来保存其“业务规则”,这些规则通常只是数学公式。
但是他们总是假设double x = 3/2; 将返回x = 1.5,但是在C#中返回1。
答:他们总是忘记了这一点,浪费了调试时间,打电话给我寻求支持,我们将其修复。 B.他们认为这很丑陋并损害了业务规则的可读性。
如您所知,DSL需要更像自然语言。
是。 我们正计划迁移到Boo,并基于Boo构建DSL,但这已经行进了。
是否有一个简单的方法可以使double x = 3/2; 通过类外部的东西返回1.5,因此用户看不到它?
谢谢! 韦恩
不,没有解决方案可以使3 / 2
返回1.5。
考虑到您的约束的唯一变通办法是不鼓励用户在公式中使用文字。 鼓励他们使用常量。 或者,如果他们确实需要使用文字,则鼓励他们使用带小数点的文字。
永不说永不...(/ 2)3/2解决方案看起来不错...
但失败了4 + 5/6
试试这个:捐赠给公共领域,供SymbolicComputation.com免费使用。
它是Alpha版,但您可以尝试一下,我只在少数测试中运行过,我的网站和软件应该很快就可以启动。 它使用Microsoft的Roslyn,如果一切顺利的话,会在每个数字后面加上一个“ d”。 Roslyn也是alpha,但是它将解析相当一部分的C#。
public static String AddDSuffixesToEquation(String inEquation)
{
SyntaxNode syntaxNode = EquationToSyntaxNode(inEquation);
List<SyntaxNode> branches = syntaxNode.DescendentNodesAndSelf().ToList();
List<Int32> numericBranchIndexes = new List<int>();
List<SyntaxNode> replacements = new List<SyntaxNode>();
SyntaxNode replacement;
String lStr;
Int32 L;
for (L = 0; L < branches.Count; L++)
{
if (branches[L].Kind == SyntaxKind.NumericLiteralExpression)
{
numericBranchIndexes.Add(L);
lStr = branches[L].ToString() + "d";
replacement = EquationToSyntaxNode(lStr);
replacements.Add(replacement);
}
}
replacement = EquationToSyntaxNode(inEquation);
List<SyntaxNode> replaceMeBranches;
for (L = numericBranchIndexes.Count - 1; L >= 0; L--)
{
replaceMeBranches = replacement.DescendentNodesAndSelf().ToList();
replacement = replacement.ReplaceNode(replaceMeBranches[numericBranchIndexes[L]],replacements[L]);
}
return replacement.ToString();
}
public static SyntaxNode EquationToSyntaxNode(String inEquation)
{
SyntaxTree tree = EquationToSyntaxTree(inEquation);
return EquationSyntaxTreeToEquationSyntaxNode(tree);
}
public static SyntaxTree EquationToSyntaxTree(String inEquation)
{
return SyntaxTree.ParseCompilationUnit("using System; class Calc { public static object Eval() { return " + inEquation + "; } }");
}
public static SyntaxNode EquationSyntaxTreeToEquationSyntaxNode(SyntaxTree syntaxTree)
{
SyntaxNode syntaxNode = syntaxTree.Root.DescendentNodes().First(x => x.Kind == SyntaxKind.ReturnStatement);
return syntaxNode.ChildNodes().First();
}
简单,如果我没记错的话:
double x = 3D / 2D;
一种解决方案是编写一种为他们做到这一点并教他们使用的方法。 您的方法将始终采用双精度,并且答案将始终具有正确的小数位数。
我不太确定,但是我相信您可以使用3.0 / 2.0来获得两倍的效果,但是如果您认为.0只是后缀的另一种方式,那么答案也不尽相同:-)
也许您现在可以尝试RPN Expression Parser Class或bcParser ? 这些是非常小的表达式解析库。
我喜欢自己的工作中使用的强大的静态类型语言,但是我认为它们不适合对成为专业人士没有兴趣的初学者。
因此,很不幸,我不得不说您选择的C#不一定适合该人群。
Boo似乎是静态键入的。 您是否考虑过嵌入Javascript引擎,Python或其他一些动态类型的引擎? 通常,将这些插入到现有应用程序中并不难,并且您可以从许多现有文档中受益。
也许是int32的扩展方法?
在将公式传递给C#编译器之前对其进行预处理。 做类似的事情:
formula = Regex.Replace(formula, @"(^|[\^\s\+\*\/-])(\d+)(?![DF\.])", "$1$2D")
将整数文字转换为双精度文字。
或者,您可以使用一个简单的状态机来跟踪您是否在字符串文字或注释中,而不是盲目地进行替换,但是对于简单的公式,我认为正则表达式就足够了。
尝试这样做:
double result = (double) 3 / 2;
结果= 1.5
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.