gpt4 book ai didi

Dart 舍入误差

转载 作者:行者123 更新时间:2023-12-03 02:50:58 25 4
gpt4 key购买 nike

所以做一个print(0.3 - 0.2);将打印 0.09999999999999998 .

我知道浮点运算对于二进制处理器来说是不可能正确的,但我希望 Dart 中内置的一些东西至少会尝试消除舍入错误。

使上面显示 0.1 需要来回进行一些转换,我宁愿不这样做:

print(num.parse((0.3 - 0.2).toStringAsPrecision(8)));

-> 0.1

我有什么选择可以不让小数变得疯狂? Dart 中是否有任何内置功能可以帮助解决此问题?似乎只有一个库可以执行上述操作: https://pub.dev/packages/decimal ?

最佳答案

您可以通过以下方式将值四舍五入为十的倍数(或任何其他数字):

double roundTo(double value, double precision) => (value * precision).round() / precision;

然后,您可以对初始值或最终结果执行此操作:
int precision = 10;
final result = roundTo(0.3 - 0.2, precision);
// or inlined:
final result = ((0.3 - 0.2) * precision).round() / precision;

这可确保对原始值进行计算,并且您只对最终结果进行四舍五入。

如果您知道您的输入值都具有相同的比例,您可以按照@brian-gorman 的建议进行操作并首先缩放值,然后最后舍入和缩小结果。对于这种用途,我建议尽早对传入的值进行舍入,以便计算不会累积不精确。
(这对于单个减法无关紧要,但对于更复杂的计算,它可能)。
final difference = (0.3 * precision).round() - (0.2 * precision).round();
final result = difference / precision;

记录:您看到的结果不是舍入错误,而是正确的结果 - 对于 IEEE-754 定义的 64 位浮点数。

您将在使用普通 double 的任何其他语言(包括 JavaScript 和 Java)中看到相同的结果。 0.3 - 0.2的结果不是表示为 0.1 的 double 值.它是一个不同的数字,所以它必须有一个不同的 toString表示。

0.1、0.2 或 0.3 都不能完全表示为 double 。实际值为:
  • 0.1 : 0.1000000000000000055511151231257827021181583404541015625
  • 0.2 : 0.200000000000000011102230246251565404236316680908203125
  • 0.3 : 0.29999999999999988897769753748434595763683319091796875
  • 0.3 - 0.2 : 0.0999999999999997779553950749686919152736663818359375

  • 所以当你写语法 0.30.2 ,您实际上是在指定上面的精确 double 值。

    结果变成这样,因为 0.3 - 0.2 的精确数学计算是
      0.299999999999999988897769753748434595763683319091796875
    - 0.200000000000000011102230246251565404236316680908203125
    = 0.099999999999999977795539507496869191527366638183593750

    结果是一个精确的 double 值。所以结果 0.09999... 正是“0.3”和“0.2”之间的差,因此是减法的正确结果。 (错误是假设您实际上将 0.3 和 0.2 作为值,而您从未这样做过)。它也与 0.1 所代表的数字不同。

    关于 Dart 舍入误差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57481767/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com