我有一个非常简短的问题,基于以下 C# 代码:
decimal _sampleCounter = 2100m;
decimal wrong = _sampleCounter % (30m / 2.3m);
decimal correct = 2100m % (30m / 2.3m);
Console.WriteLine(wrong); // -> 13.043478260869565217391304320
Console.WriteLine(correct); // -> 0.0000000000000000000000000
错误的结果等于使用双精度而不是十进制时的结果。 数学上正确的结果确实是 0。
那么这里发生了什么?为什么这两种情况都不是 0.0000...? 我可以想象编译器直接将变量“正确”转换为其最终值,但这并不能解释为什么两个结果不同。
最诚挚的问候, 菲利普
编辑1: 我的配置是:环境版本:.NET 8.0.6(8.0.6),Microsoft Windows NT 10.0.22631.0。默认、IgnoreSymbolStoreSequencePoints、EnableEditAndContinue、DisableOptimizations
编辑2: 好吧,根本问题是我需要检查 (30 / 2.3) 何时除 2100 没有余数。我找到了一个解决方法,只需进行除法,然后检查小数位是否等于 0:
decimal.Compare((2100m / (30m / 2.3m)) % 1m,0m)
这在我的具体情况下就可以完成工作。对此有何评论?就我而言,这也适用于双精度而不是十进制。
假设某些版本的编译器可以转换表达式:
decimal correct = 2100m % (30m / 2.3m);
至:
decimal correct = ((2100m * 2.3m) % 30m) / 2.3m;
计算前。
在这种情况下:4830m % 30m = 0