4 minutes read

We often use real numbers to perform calculations in science, statistics, engineering, and other fields. Kotlin has two basic types to represent real numbers: Float and Double. They are called floating-point types. In fact, these types cannot represent an arbitrary real number because they support only a limited number of significant decimal digits (6-7 for Float and 14-16 for Double). In addition, Double can represent a wider number range than Float.

In practice, programmers mostly use the Double type. We will discuss this type, and we do recommend using it to solve our code challenges. However, all the information below is true for the Float type as well.

Floating-point arithmetic operations

It is easy to create a variable of a Double type:

val one = 1.0
val negNumber = -1.75

val pi = 3.1415

If you want to create a Float, make the following statement:

val b: Float = 8.75f

val e = 2.71828f

Arithmetic operations with Doubles can be performed like this:

val number = one + 1.5 // 2.5
val c = b + negNumber  // 7, Double, the type is inferred from the context

val squaredPi = pi * pi // 9.86902225

For fractional operands, the operator / performs division with a remainder, not integer division.

println(squaredPi / 2) // prints 4.934511125

Errors during computation

Be careful — operations with floating-point numbers can produce an inaccurate result:

println(3.3 / 3) // prints 1.0999999999999999

Errors can accumulate during computation:

val num = 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1
println(num) // it prints 0.9999999999999999

In the following topics, we will find out how to deal with this problem, but for now, just consider it.

Reading numbers

You can use readln() to read Doubles and Floats from the standard input:

val f = readln().toFloat()  // Float
val d = readln().toDouble() // Double

For example, consider a program that calculates a triangle area. To find it, the program reads the base and the height from the standard input, then multiplies them and divides the result by 2. Note that the base and the height are perpendicular to each other.

fun main() {
    val base = readln().toDouble()
    val height = readln().toDouble()

    val area = (base * height) / 2

    println(area)
}

Let's calculate the area of a triangle with the base of 3.3 and the height of 4.5:

Input 1:

3.3
4.5

Output 1:

7.425

Remember that the output might contain many zeroes, as shown below, because operations with floating-point numbers can produce inexact results. This happens because computers work with binary numbers, and many floating-point numbers cannot be represented finitely in base 2. Working with these inexact numbers leads to imprecise results:

Input 2:

2.2 4.01

Output 2:

4.4110000000000005

It is possible to round or format a double result, but we will discuss it later.

Decimal separator

It is crucial to use the correct decimal separator. The separator is locale-dependent, such as a dot for the US locale. If you happen to employ any other character, it may crash your program. If you work with another locale and want to use the dot character, you can use this construction:

import java.util.Locale

val floatNum = readln().format(Locale.US).toFloat()

Conclusion

In this topic, we have discussed the two main floating-point types in Kotlin — Float and Double. There are subtle differences between them, but they share one common feature — you can use them for carrying out arithmetic operations with floating-point numbers. Remember, floating-point types may produce inaccurate results, so account for that. And don't forget about the correct decimal separator, too!

446 learners liked this piece of theory. 7 didn't like it. What about you?
Report a typo