如何强制c#binary int division返回double?

时间:2010-03-21 04:11:22

标签: c# casting int dsl division

如何强制加倍x = 3/2;在没有D后缀或铸造的情况下返回1.5 in x?是否有任何类型的操作员过载可以完成?还是一些编译器选项?

令人惊讶的是,由于以下原因,添加转换或后缀并不是那么简单:

业务用户需要编写和调试自己的公式。目前,C#正在被用作DSL(领域特定语言),因为这些用户不是计算机科学工程师。所以他们所知道的是如何编辑和创建几种类来保存他们的“业务规则”,这些规则通常只是数学公式。

但他们总是假设双x = 3/2;将返回x = 1.5 但是在C#中返回1。

一个。他们总是忘记这一点,浪费时间调试,打电话给我寻求支持,我们修复它。 B.他们认为这非常丑陋并且损害了他们的业务规则的可读性。

如您所知,DSL需要更像自然语言。

是。我们计划转移到Boo并建立一个基于它的DSL,但这是在未来。

是否有一个简单的解决方案,使双x = 3/2;通过类外部的东西返回1.5,这样对用户来说是不可见的吗?

谢谢! 韦恩

9 个答案:

答案 0 :(得分:5)

不,没有解决方案可以使3 / 2返回1.5。

考虑到您的约束的唯一解决方法是阻止用户在公式中使用文字。鼓励他们使用常数。或者,如果他们真的需要使用文字,鼓励他们使用带小数点的文字。

答案 1 :(得分:1)

永远不要说永远...... (双)3/2解决方案看起来不错......

但是4 + 5/6

失败了

试试这个: 捐赠给公共领域,由SymbolicComputation.com自由使用 这是alpha,但你可以尝试一下,我只在几次测试中运行它,我的网站和软件应该很快就会出现。 它使用微软的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();
    }

答案 2 :(得分:0)

简单,如果我没弄错的话:

double x = 3D / 2D;

答案 3 :(得分:0)

一种解决方案是编写一种方法,为他们执行此操作并教他们使用它。您的方法将始终采用双精度数,答案将始终具有正确的小数位数。

答案 4 :(得分:0)

我不太确定,但我相信你可以使用3.0 / 2.0获得双倍 但是如果你认为.0就像另一种后缀方式那么它也不是答案: - )

答案 5 :(得分:0)

也许您现在可以尝试RPN Expression Parser ClassbcParser?这些是非常小的表达式解析库。

我喜欢使用强大的静态类型语言来完成自己的工作,但我不认为它们适合那些对成为专业人士没兴趣的初学者。

所以我不得不说,不幸的是,您选择的C#可能并不是最适合观众的。

Boo似乎是静态输入的。您是否考虑过嵌入Javascript引擎,Python或其他动态类型的引擎?这些通常并不难以插入现有的应用程序,并且您可以从许多现有文档中获益。

答案 6 :(得分:0)

也许是int32上的扩展方法?

答案 7 :(得分:0)

在将公式传递给c#编译器之前预处理公式。做类似的事情:

formula = Regex.Replace(formula, @"(^|[\^\s\+\*\/-])(\d+)(?![DF\.])", "$1$2D")

将整数文字转换为双重文字。

或者,您可以使用一个简单的状态机来跟踪您是否在字符串文字或注释中而不是盲目地替换,但对于简单的公式,我认为正则表达式就足够了。

答案 8 :(得分:0)

尝试这样做:

double result = (double) 3 / 2;

结果= 1.5