在托管 C++ 中解析双精度值时,我遇到了一个奇怪的问题。可能是我做错了什么。当我做:
double value = 0.006;
result = Math::Parse( value)
结果的输出是0.006000000000001
。为什么它附加一个1?
此外,当我将值四舍五入到小数点后 5 位时,它会失败。我在做:
result2 = Math::Round(result, 5)
但result2
总是0.006000000000001
。我究竟做错了什么?
在托管 C++ 中解析双精度值时,我遇到了一个奇怪的问题。可能是我做错了什么。当我做:
double value = 0.006;
result = Math::Parse( value)
结果的输出是0.006000000000001
。为什么它附加一个1?
此外,当我将值四舍五入到小数点后 5 位时,它会失败。我在做:
result2 = Math::Round(result, 5)
但result2
总是0.006000000000001
。我究竟做错了什么?
这是由于精度。我在这里给出了这个答案:
浮点数和双精度数是具有一定精度的数字表示。并非每个值都可以用这种格式表示。也见 这里。
您可以很容易地想到为什么会这样:在区间 (1..1) 中有无限数量的数字,但浮点数只有有限数量的位来表示 (-MAXFLOAT..最大浮动)。
更恰当地说:在 32 位整数表示中,有可数个整数要表示,但有无数个实数值无法在 32 位或 64 位的有限表示中完全表示。因此,不仅对最高和最低可表示的实际值有限制,而且对准确性也有限制。
那么为什么浮点数后位数很少的数字会受到影响呢?因为表示是基于二进制系统而不是十进制的,所以其他数字比十进制更容易表示。
双精度数本质上是近似值,并且经常有你无法摆脱的尾巴- 即没有办法更准确地表达数字。
如果您使用decimal
- 这仍然是一个近似值,但它使用 base-10,您可能会得到更符合您预期的结果,因此往往表现得更像人们期望的那样。但因为它没有映射到 CPU 类型,所以速度较慢。
这是正常的。这个问题由 IEEE 格式的 double - in real 0.006 表示为无限二进制小数的近似值。所以你有3种方法 -