Dart、float for 循环会导致奇怪的结果

标签 dart angular-dart dart-html

for(int i=0; i<10; i++) {
    priceValue.add(54.99 + i*5);
    print(54.99 + i*5);
}

结果:

js_primitives.dart:30 54.99
js_primitives.dart:30 59.99
js_primitives.dart:30 64.99000000000001
js_primitives.dart:30 69.99000000000001
js_primitives.dart:30 74.99000000000001
js_primitives.dart:30 79.99000000000001
js_primitives.dart:30 84.99000000000001
js_primitives.dart:30 89.99000000000001
js_primitives.dart:30 94.99000000000001
js_primitives.dart:30 99.99000000000001

什么原因导致出现00000000001

最佳答案

这就是双数的工作原理。在使用与 Dart 相同的 double 的其他语言中,您会得到相同的结果(它们被标准化为 IEEE-754 64-bit floating point numbers )。

关键在于,例如 89.99 不能用 double 精确表示。 double 是最多有 53 个有效位的二进制数。 在二进制中,89.99 没有有限的表示形式,就像 1/3 不能有限地写成十进制数一样(0.3333333....对于精确值来说永远不够)。

只有有限数量的 double 值,分布在 double 值覆盖的范围内。因此,当您尝试将“实数”转换为 double 时,计算机将四舍五入到与原始数字最接近的 double 值。

即使是 54.99 也不精确。 54.99 的实际 double 值是最接近数学数字 54.99(又名 5499/100)的 double:

54.99000000000000198951966012828052043914794921875

然后添加 35,这同样不能表示为 double ,并且 double 硬件会选择最接近该值的 double :

89.990000000000009094947017729282379150390625

由于原始 54.99 的不精确性,这实际上与仅编写 89.99 时选择的 double 不同,即:

89.9899999999999948840923025272786617279052734375

当您将 double 转换为字符串时,选择表示形式的算法实际上很聪明。它选择最短十进制表示形式,其中数值将四舍五入为原始 double 值。

因此,由于 54.99 + 3589.99 不同,因此它们需要具有不同的字符串表示形式。字符串 89.99 显然是后者,因此 54.99 + 35 需要更多的数字来区分自己。这就是尾随 00000000000001 的来源。

所以,简而言之,这就是 double 所做的事情。在使用相同 double 类型的大多数其他语言中,相同的计算将给出相同的结果。

关于Dart、float for 循环会导致奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44557990/

相关文章:

dart - 使用 Dart lang 为 "pseudo-element"设置样式

dart - 在 Dart 中,是否存在与使用 WinForms 的 C# 中等效的 MessageBox 功能

dart - 访问 Dart 中的继承字段

json - 将 JSON 日期加载到 Dart DateTime

android - 在 flutter 项目中为 android 模块使用自定义名称

javascript - ChartJs beforeDraw 方法在发布版本中没有被调用

dart - 无法使用简单的 Dart Web 服务器来提供角度组件

dart - 如何在Dart应用程序中播放音频

dart - 选择更改后, paper 单选按钮波纹仍然存在

Flutter 全局 Http 拦截器