c#中的计算与Windows计算器一样精确

本文关键字:一样 计算器 计算 Windows | 更新日期: 2023-09-27 18:06:15

当我在c# 100.0 * 1.005中执行以下双重乘法时,我得到100,49999999999999作为结果。我认为这是因为无法表示确切的数字(或计算表达式时的一些中间结果)。当我在calc.exe中进行相同的计算时,我得到了100.5

另一个例子是0.001的9倍增量(这是第一次发生偏差),所以基本上是9d * 0.001d = 0,0090000000000000011。当我在calc.exe中进行相同的计算时,我得到了0.009

现在有人会说,我应该选择小数。但是对于十进制,我在其他计算中遇到问题,例如使用((1M / 3M) * 3M) = 0,9999999999999999999999999999,而calc.exe显示1

使用calc.exe,我可以将1除以3多次,直到一些真正的小数字,然后再乘以3多次,然后我达到确切的1。因此,我怀疑calc.exe在内部计算分数,但显然是真正的大分数,因为它计算

(677605234775492641 / 116759166847407000) + (932737194383944703 / 2451942503795547000)

,其中公分母是-3422539506717149376(发生溢出),当进行长计算时,因此它必须至少为ulong。有人知道calc。exe中的计算是如何实现的吗?这个实现是否在某个地方公开以供重用?

c#中的计算与Windows计算器一样精确

如这里所述,calc使用任意精度引擎进行计算,而double是标准的IEEE-754算术,decimal也是浮点算术,只是在十进制中,正如您指出的,它有同样的问题,只是在另一种进制中。

你可以尝试为c#找到这样一个任意精度的算术库并使用它,例如这个(不知道它是否好;这是第一个结果)。calc里面的那个不能作为API使用,所以你不能使用它。

另一点是,当您将结果四舍五入到一定位数(小于15位)时,在许多情况下您也会得到直观的"正确"结果。c#已经做了一些舍入来隐藏double的确切值(其中0.3绝对不是0.3,但可能类似0.30000000000000004)。通过减少显示的位数,可以减少与正确值之间如此微小差异的发生。