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

发布于 2024-08-25 18:00:36 字数 521 浏览 6 评论 0原文

如何强制 double x = 3 / 2;返回 1.5 in x 而不带 D 后缀或转换?是否可以实现任何类型的运算符重载?或者一些编译器选项?

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

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

但他们总是假设 double x = 3 / 2;将返回 x = 1.5 然而在 C# 中,返回 1.A。

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

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

是的。我们计划迁移到 Boo 并基于它构建一个 DSL,但这只是未来的事情。

有没有一个简单的解决方案使 double x = 3 / 2;通过类外部的东西返回 1.5,以便用户看不到它?

谢谢! 韦恩

How to force double x = 3 / 2; to return 1.5 in x without the D suffix or casting? Is there any kind of operator overload that can be done? Or some compiler option?

Amazingly, it's not so simple to add the casting or suffix for the following reason:

Business users need to write and debug their own formulas. Presently C# is getting used like a DSL (domain specific language) in that these users aren't computer science engineers. So all they know is how to edit and create a few types of classes to hold their "business rules" which are generally just math formulas.

But they always assume that double x = 3 / 2; will return x = 1.5
however in C# that returns 1.

A. they always forget this, waste time debugging, call me for support and we fix it.
B. they think it's very ugly and hurts the readability of their business rules.

As you know, DSL's need to be more like natural language.

Yes. We are planning to move to Boo and build a DSL based on it but that's down the road.

Is there a simple solution to make double x = 3 / 2; return 1.5 by something external to the class so it's invisible to the users?

Thanks!
Wayne

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

我不咬妳我踢妳 2024-09-01 18:00:36

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

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

No, there's no solution that can make 3 / 2 return 1.5.

The only workaround taking into consideration your constraints is to discourage the users to use literals in the formula. Encourage them to use constants. Or, if they really need to use literals, Encourage them to use literals with a decimal point.

送舟行 2024-09-01 18:00:36

永不说永不...
(double)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();
    }

never say never...
The (double)3/2 solution looks nice...

but it failed for 4+5/6

try this:
donated to the public domain to be used freely by SymbolicComputation.com.
It's alpha but you can try it out, I've only run it on a few tests, my site and software should be up soon.
It uses Microsoft's Roslyn, it'll put a 'd' after every number if all goes well. Roslyn is alpha too, but it will parse a fair bit of 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();
    }
寄与心 2024-09-01 18:00:36

很简单,如果我没记错的话:

double x = 3D / 2D;

simple, if I'm not mistaken:

double x = 3D / 2D;
时光倒影 2024-09-01 18:00:36

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

One solution would be writing a method that does this for them and teach them to use it. Your method would always take in doubles and the answer will always have the correct number of decimals.

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

I'm not pretty sure, but I believe you can get a double using 3.0/2.0
But if you think .0 just as another way of suffixing then it's not the answer too :-)

嘿嘿嘿 2024-09-01 18:00:36

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

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

因此,我不得不说,不幸的是,您选择的 C# 可能不是最适合该受众的。

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

Maybe you can try RPN Expression Parser Class for now or bcParser? These are very small expression parsing libraries.

I like strong, statically typed languages for my own work, but I don't think they're suited for beginners who have no interest in becoming professionals.

So I'd have to say unfortunately your choice of C# might not of been the best for that audience.

Boo seems to be statically typed to. Have you thought about embedding a Javascript engine, Python, or some other dynamically typed engine? These usually are not that hard to plug into an existing application and you have the benefit of lots of existing documentation.

春庭雪 2024-09-01 18:00:36

也许是 int32 上的扩展方法?

Perhaps an extenstion method on int32?

轻拂→两袖风尘 2024-09-01 18:00:36

在将公式传递给 C# 编译器之前对其进行预处理。执行以下操作:

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

将整数文字转换为双精度文字。

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

Preprocess formulas before passing them to the c# compiler. Do something like:

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

To convert integer literals to double literals.

Alternately, you could use a simple state machine to track whether or not you're in a string literal or comment rather than blindly replacing, but for simple formulas I think a regex will suffice.

七婞 2024-09-01 18:00:36

尝试这样做:

double result = (double) 3 / 2;

结果= 1.5

Try doing it like this:

double result = (double) 3 / 2;

result = 1.5

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文