Dennis Schröder
Dennis Schröder

Reputation: 31

Kotlin double greater than float wrong expression resolving

I ran into an issue which I was wondering if the expected behavior is correct or whether I found a bug.

Given this:

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

0.08.toFloat() > 0.08F == false

Why does the third expression is not false? Any ideas?

Upvotes: 2

Views: 1830

Answers (2)

Patricia Shanahan
Patricia Shanahan

Reputation: 26185

This is a supplement to the existing answer. Java BigDecimal has two useful properties for analyzing floating point behavior. Conversion from float or double to BigDecimal is exact, and so is its default string conversion. The simplest use of these properties is to print the exact value of a floating point expression. BigDecimal arithmetic can also be used, for example, to find the half way points between a double and its neighbors when studying rounding.

This program:

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));
    }
}

outputs:

0.08000000000000000166533453693773481063544750213623046875
0.07999999821186065673828125

which confirms that 0.08 is represented to the expected precision in each format, and the double representation is strictly greater than the float.

Upvotes: 3

ich5003
ich5003

Reputation: 838

It is not a bug, it's based on rounding errors.

Executing the following code:

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))

gives you the following output:

0.08000000000000000000
0.07999999821186066000
0.07999999821186066000

So as you can see, 0.08 double value is (till the 20th decimal place) exact to 0.08 while the float is (due to lower precision) not able to be represented as exact so it contains a rounded value, which is slightly lower than 0.08

Converting your approximate (a little lower) 0.08 float to a double doesn't increase your precision, you still have your rounding error of the float, which results in being the converted double to be a little bit lower.

// Edit: If you are interested in how exactly floating point numbers work, I would recommend you to have a look at the wikipedia article on floating point arithmetic and at this question: Is floating point math broken?

Upvotes: 4

Related Questions