托管 C++ 中的 double.Parse 问题
-
11-09-2019 - |
题
我在解析托管 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类型,它是较慢的。
不隶属于 StackOverflow