我正在构建一个 WPF 计算器应用程序,在测试它时(与 Windows 内置计算器的行为进行比较)我发现了一些差异。
这是我的一项测试的打印结果:
测试“Comparison.Tests.ComparisonTests”失败:
预期字符串长度为 17,但实际长度为 16。字符串在索引 16 处不同。
预期:“175641.7874709774”
但是是:“175641.787470977”
我使用 double 进行所有计算,最后将它们作为字符串显示到文本框。
造成这种差异的原因是什么? double 不足以存储基本运算(加、乘、减、除、SQRT 等)的结果。
如果您愿意接受其局限性(15-16 位精度),双精度就足够了。
如果您使用 Windows 计算器作为黄金标准,您应该知道它内部不使用 Double - 它在 Windows 95 中被重写为使用任意精度算术库。根据 Raymond Chen 的博客文章:
如今,Calc 的内部计算对于基本运算(加法、减法、乘法、除法)以无限精度完成,对于高级运算(平方根、超越运算符)以 32 位精度完成。大多数应用程序不需要超过 15 位的精度。如果您这样做,您需要找到一个支持任意精度数学的库。
Double
类型为您提供大约 15 位十进制数字的精度,因此看起来您确实遇到了该限制。
Decimal
使用 128 位,而不是像
Double
那样使用 64 位,这样可以在相似的范围内提供更高的精度。
十进制将为您提供 96 位精度(128 位值)。
前者的指数为二进制,后者的指数为十进制,这意味着 double 中的“四舍五入”数字可能比十进制中的数字更让用户感到惊讶。
另一方面,小数在需要表示无穷大或非数字的情况下表现不佳。
最有可能的是,十进制将更好地服务于双精度。如果您需要更高的精度,您可以通过组合
BigInteger
和一个数字来保持刻度,从而滚动您自己的大十进制。