Kotlin double大于浮点错误表达式解析

Kotlin double大于浮点错误表达式解析,kotlin,floating-point,double,expression,Kotlin,Floating Point,Double,Expression,我遇到了一个问题,我想知道预期的行为是否正确,或者我是否发现了一个bug 鉴于此: 0.08 > 0.08 == false 0.08 > 0.08F == true 0.08 > 0.08F.toDouble() == true 0.08.toFloat() > 0.08F == false 为什么第三个表达式不是假的? 有什么想法吗?这不是一个bug,它是基于舍入误差 执行以下代码: val d = 0.08 val f = 0.08F val fd = f.to

我遇到了一个问题,我想知道预期的行为是否正确,或者我是否发现了一个bug

鉴于此:

0.08 > 0.08 == false
0.08 > 0.08F == true
0.08 > 0.08F.toDouble() == true

0.08.toFloat() > 0.08F == false
为什么第三个表达式不是假的?
有什么想法吗?

这不是一个bug,它是基于舍入误差

执行以下代码:

val d = 0.08
val f = 0.08F
val fd = f.toDouble()
print("%.20f".format(d) + "\n")
print("%.20f".format(f) + "\n")
print("%.20f".format(fd))
提供以下输出:

0.08000000000000000000
0.07999999821186066000
0.07999999821186066000
如您所见,0.08 double value(直到小数点后20位)精确到0.08,而float(由于精度较低)无法表示为精确,因此它包含一个四舍五入值,略低于0.08

将近似值(稍微低一点)0.08浮点值转换为双精度不会提高精度,但仍然存在浮点值的舍入误差,这会导致转换后的双精度值稍微低一点


//编辑:如果您对浮点数的确切工作方式感兴趣,我建议您查看,并回答以下问题:

这是对的补充。Java
BigDecimal
有两个用于分析浮点行为的有用属性。从
float
double
BigDecimal
的转换是精确的,其默认字符串转换也是精确的。这些属性最简单的用途是打印浮点表达式的精确值<例如,在研究舍入时,还可以使用code>BigDecimal算法来查找
double
与其邻居之间的中间点

该计划:

import java.math.BigDecimal;

public strictfp class Test {
    public static void main(String[] args) {
        System.out.println(new BigDecimal(0.08));
        System.out.println(new BigDecimal(0.08f));
    }
}
产出:

0.08000000000000000166533453693773481063544750213623046875
0.07999999821186065673828125
这证实了0.08表示为每种格式的预期精度,
double
表示严格大于
float

最后一个链接to不是一个好的参考。那里的答案通常不是教程,通常试图用一种或另一种理由“解释”错误,而不是给出学生使用浮点运算所需的背景和数学公式。