为什么在 dart 中将两个 double 相乘会得到非常奇怪的数字

mac*_*rix 4 double int dart

谁能解释为什么结果是 252.99999999999997 而不是 253?应该用什么来代替得到253?

\n\n
double x = 2.11;\ndouble y = 0.42;\nprint(((x + y) * 100)); // print 252.99999999999997\n
Run Code Online (Sandbox Code Playgroud)\n\n

我基本上试图将小数点后 2 位的货币值(即 \xc2\xa32.11)转换为便士/分(即 211p)\n谢谢

\n

lrn*_*lrn 6

简而言之:因为许多小数双精度值并不精确,并且添加不精确的值可能会产生更不精确的结果。这是 IEEE-754 浮点数的固有属性,也是 Dart(以及大多数其他语言和运行它们的 CPU)所使用的。

有理数 2.11 和 0.42 都不能精确地表示为一个double值。当您编写2.11源代码时,其含义是double最接近数学数字 2.11 的实际值。

的值2.11正好是 2.109999999999999875655021241982467472553253173828125。的值0.42正好是 0.419999999999999984456877655247808434069156646728515625。正如您所看到的,两者都比您预期的值稍小。

然后将这两个值相加,得到精确double结果 2.529999999999999804600747665972448885440826416015625。这会丢失四舍五入的最后几位数字0.42,并且由于两者都已经小于 2.11 和 0.42,因此结果现在甚至比 2.53 更小。最后将其乘以 100,得到精确结果 252.999999999999971578290569595992565155029296875。

这与双精度值 253.0 不同。

double.toString方法不会返回精确值的字符串,但它确实会针对不同的值返回不同的字符串,并且由于该值与 253.0 不同,因此它必须返回不同的字符串。然后,它返回一个最短数字的字符串,该数字仍然比下一个相邻的双精度值更接近结果,这就是您看到的字符串。