scala - 为什么 0.29999999999999998 转换为 0.3?

标签 scala floating-point precision

它在内部如何运作?

怎么决定转换0.299999999999999980.3 ,即使 0.3不能用二进制表示?

这里还有一些例子:

scala> 0.29999999999999998
res1: Double = 0.3

scala> 0.29999999999999997
res2: Double = 0.3

scala> 0.29999999999999996
res3: Double = 0.29999999999999993

scala> 0.29999999999999995
res4: Double = 0.29999999999999993

最佳答案

涉及两个转换。

首先将 0.29999999999999998 转换为 0.299999999999999988897769753748434595763683319091796875,这是最接近的可表示数。

接下来将0.29999999999999988897769753748434595763683319091796875转换为十进制进行打印。 0.3 也是转换为 0.29999999999999988897769753748434595763683319091796875 的数字之一,因为它太短而被打印出来。

每个有限双数都可以精确地表示为小数。通常,默认输出不会尝试打印确切的值,因为它可能很长 - 比上面的示例长得多。一个常见的选择是打印最短的小数部分,以便在输入时转换为 double 数。两种转换都是使用非平​​凡算法完成的。见 Algorithm to convert an IEEE 754 double to a string?有关输出算法的一些讨论和引用。

================================================== ============

在评论中对值 0.30000000000000004 进行了一些讨论。我同意 Rick Regan 和 Jesper 的评论,但认为添加到这个答案可能有用。

最接近 0.30000000000000004 的精确值是 0.3000000000000000444089209850062616169452667236328125。范围内的所有十进制数 [0.3000000000000000166533453693773481063544750213623046875, 0.30000000000000000721644966056230353523523523535235235353523535353535353535之外0.3000000000000000 超出范围,因此没有足够的位数。 0.30000000000000004 在范围内,因此不需要更多数字来正确识别 double 数。

关于scala - 为什么 0.29999999999999998 转换为 0.3?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34081470/

相关文章:

scala 内联函数 - "ar.reduce((x,y) => x)"有效,但 "ar.reduce{case(x,y) => x}"无效

scala - 类对象继承/协变

algorithm - Scala 中最快的加权随机算法?

scala - 查找 Spark 阶段每个步骤的执行时间

c++ - 整数除法是否需要强制转换为 float 或 double 才能更精确?

python - 如何在 python 中将数字转换为 12 位精度?

c++ - float 的验证和转换

sql - 为什么即使提供了准确的数据,FLOAT 类型的数据比较也不起作用

python - 如何查看数字是否以 .0 结尾

c# - 为什么在 C# 中添加多个 double 时顺序会影响舍入