这就是双数字的工作原理.您将在使用与Dart相同的双精度的其他语言中获得相同的结果(它们被标准化为IEEE-754 64位浮点数).
关键是,例如,89.99无法用双精度精确表示.双打是二进制数,最多有53位有效位.在二进制中,89.99没有有限的表示,就像1/3不能有限地写成十进制数(0.3333333 ......它对于精确值来说永远不够).
只有有限数量的双值,在整个范围内扩展,覆盖率翻倍.因此,当您尝试将"真实"数字转换为双精度数时,计算机将舍入到与原始数字最接近的双精度值.
甚至54.99都不准确.实际的double值54.99
是最接近数学数字54.99(又名5499/100)的双精度值:
54.99000000000000198951966012828052043914794921875
然后你添加35,再次不能表示为double,双硬件选择最接近该值的双倍:
89.990000000000009094947017729282379150390625
由于原始54.99的不精确,这实际上是一个不同于仅用于写作的选择的双倍89.99
,这是:
89.9899999999999948840923025272786617279052734375
将double转换为字符串时,选择表示的算法实际上很聪明.它选择最短的十进制表示,其中数值将四舍五入为原始双精度值.
因此,由于它们54.99 + 35
不是同一个89.99
,它们需要具有不同的字符串表示.字符串89.99
显然是针对后者的,因此54.99 + 35
需要更多的数字来区分自己.这就是尾随的00000000000001
来源.
所以,简而言之,这就是双打所做的事情.在使用相同double类型的大多数其他语言中,相同的计算将得到相同的结果.
这就是双数字的工作原理.您将在使用与Dart相同的双精度的其他语言中获得相同的结果(它们被标准化为IEEE-754 64位浮点数).
关键是,例如,89.99无法用双精度精确表示.双打是二进制数,最多有53位有效位.在二进制中,89.99没有有限的表示,就像1/3不能有限地写成十进制数(0.3333333 ......它对于精确值来说永远不够).
只有有限数量的双值,在整个范围内扩展,覆盖率翻倍.因此,当您尝试将"真实"数字转换为双精度数时,计算机将舍入到与原始数字最接近的双精度值.
甚至54.99都不准确.实际的double值54.99
是最接近数学数字54.99(又名5499/100)的双精度值:
54.99000000000000198951966012828052043914794921875
然后你添加35,再次不能表示为double,双硬件选择最接近该值的双倍:
89.990000000000009094947017729282379150390625
由于原始54.99的不精确,这实际上是一个不同于仅用于写作的选择的双倍89.99
,这是:
89.9899999999999948840923025272786617279052734375
将double转换为字符串时,选择表示的算法实际上很聪明.它选择最短的十进制表示,其中数值将四舍五入为原始双精度值.
因此,由于它们54.99 + 35
不是同一个89.99
,它们需要具有不同的字符串表示.字符串89.99
显然是针对后者的,因此54.99 + 35
需要更多的数字来区分自己.这就是尾随的00000000000001
来源.
所以,简而言之,这就是双打所做的事情.在使用相同double类型的大多数其他语言中,相同的计算将得到相同的结果.