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中的计算是如何实现的吗?这个实现是否在某个地方公开以供重用?
如这里所述,calc
使用任意精度引擎进行计算,而double
是标准的IEEE-754算术,decimal
也是浮点算术,只是在十进制中,正如您指出的,它有同样的问题,只是在另一种进制中。
你可以尝试为c#找到这样一个任意精度的算术库并使用它,例如这个(不知道它是否好;这是第一个结果)。calc
里面的那个不能作为API使用,所以你不能使用它。
另一点是,当您将结果四舍五入到一定位数(小于15位)时,在许多情况下您也会得到直观的"正确"结果。c#已经做了一些舍入来隐藏double
的确切值(其中0.3
绝对不是0.3
,但可能类似0.30000000000000004
)。通过减少显示的位数,可以减少与正确值之间如此微小差异的发生。