繁体   English   中英

如何强制c#二进制int除法返回双精度?

[英]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 ClassbcParser 这些是非常小的表达式解析库。

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

因此,很不幸,我不得不说您选择的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM