我在解析托管 C++ 中的双精度值时遇到一个奇怪的问题。可能是我做错了什么。当我做:

double value = 0.006;
result = Math::Parse( value)

结果的输出是 0.006000000000001. 。为什么要加1呢?

另外,当我将值四舍五入到小数点后 5 位时,它会失败。我在做:

result2 = Math::Round(result, 5)

result2 总是 0.006000000000001. 。我究竟做错了什么?

有帮助吗?

解决方案

这是正常的。这个问题是由 IEEE 格式的 double - 实际上 0.006 表示为无限二进制分数的近似值引起的。所以你有3种方法——

  • 使用相应的字符串格式来输出
  • 使用十进制类型
  • 不要使用 == 来比较数字,而是使用 < 或 > 来比较常数错误,例如:(X -0.06) < 错误

其他提示

这是由于精确度。我这里给了这个答案

  

和双精度浮点数是数   具有一定交涉   精确。不是每个值可以是   在此格式表示。看到   这里为好。

     

您可以很容易地想到为什么这会   是这样的:有一个无限   许多刚刚在数INTERVALL   (1..1),但浮子只具有有限的   的比特数来表示所有   号码(-MAXFLOAT..MAXFLOAT)。

     

更恰当的说:在一个32位的整数   表示有一个可数   要表示的整数的数目,   但有一个无限无数   实际值的数量不能   在有限的完全表示   的32位或64位表示。   因此,有不仅是一个限制   最高和最低的可表示   真实值,也能精度。

     

那么,为什么有一个小数目   浮点数字后   受影响?因为表现   基于二进制系统,而不是在   小数,容易使其它号码   然后表示十进制的。

双精度数基本上是近似的,并且经常有问题,您尾巴无法摆脱 - 即没有更准确地表达数量的方式

您可能会得到,如果你使用decimal结果更像是你期待的 - 这仍然是一个近似值,但它使用基地10,所以往往会表现得更像人们期待。但是,因为它不映射到CPU类型,它是较慢的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top