Неточные вычисления в Kotlin
Давайте теперь посмотрим, почему дробный счет иногда расходится с обычной арифметикой.
В битах дробь собирается из половин, четвертей,
восьмых и таких же следующих долей. Если число
складывается из этих долей без хвоста, оно лежит
в памяти точно. 0.5 - это половина,
0.25 - четверть:
println(0.5 + 0.25) // 0.75
Десятая доля из таких кусков не складывается.
В десятичной записи не кончается 1/3,
в битах так же не кончается 0.1.
В Double помещается ближайшее значение
примерно на 15 значащих цифр, как в таблице.
У Float цифр около 7, зазор крупнее.
На экран 0.1 все равно выходит коротко:
печать показывает самую короткую десятичную запись,
которая совпадает с лежащими в памяти битами:
println(0.1) // 0.1
Зазор проявляется в действии. Складываются не
написанные десятые, а те ближайшие значения,
которые реально лежат в байтах. Их сумма не
совпадает с тем, как в памяти лежит 0.3,
и короткая печать уже не спасает:
println(0.1 + 0.2) // 0.30000000000000004
Вычитание устроено так же. Из памяти берутся ближайшие значения, и разность может не совпасть с привычной десятой:
println(0.3 - 0.1) // 0.19999999999999998
Умножение перемножает хранимые значения, а не школьные десятые:
println(0.1 * 3.0) // 0.30000000000000004
Хвост виден не в каждом действии. Иногда сумма двух приближенных чисел попадает в значение, чья короткая запись снова привычная:
println(0.1 + 0.1) // 0.2
Даны две переменные:
val num1 = 0.1
val num2 = 0.7
Найдите сумму этих переменных и выведите ее.
Посмотрите, совпадает ли вывод с 0.8.
Даны две переменные:
val num1 = 0.2
val num2 = 0.1
Найдите сумму этих переменных и выведите ее.
Посмотрите, совпадает ли вывод с 0.3.
Даны две переменные:
val num1 = 0.25
val num2 = 0.25
Найдите сумму этих переменных и выведите ее.
Посмотрите, совпадает ли вывод с 0.5.
Даны две переменные:
val num1 = 0.3
val num2 = 0.2
Найдите разность этих переменных: вычтите вторую
из первой и выведите ее. Посмотрите, совпадает
ли вывод с 0.1.
Даны две переменные:
val num1 = 0.4
val num2 = 0.1
Найдите разность этих переменных: вычтите вторую
из первой и выведите ее. Посмотрите, совпадает
ли вывод с 0.3.
Даны две переменные:
val num1 = 0.1
val num2 = 0.2
Найдите произведение этих переменных и выведите его.
Посмотрите, совпадает ли вывод с 0.02.
Даны две переменные:
val num1 = 0.2
val num2 = 3.0
Найдите произведение этих переменных и выведите его.
Посмотрите, совпадает ли вывод с 0.6.
Даны две переменные:
val num1 = 0.5
val num2 = 0.5
Найдите произведение этих переменных и выведите его.
Посмотрите, совпадает ли вывод с 0.25.
Даны три переменные:
val num1 = 0.1
val num2 = 0.2
val num3 = 0.3
Найдите сумму этих переменных и выведите ее.
Посмотрите, совпадает ли вывод с 0.6.