Сравнение дробных чисел в C#
Дробный счет иногда расходится с обычной
арифметикой. В памяти лежит приближенное
значение, и == с литералом часто
не совпадает, хотя на экране цифры похожи.
В битах дробь собирается из половин, четвертей,
восьмых и таких же следующих долей. Если число
складывается из этих долей без хвоста, оно лежит
в памяти точно. 0.5 - это половина,
0.25 - четверть:
double num = 0.5 + 0.25;
Console.WriteLine(num); // prints 0.75
Десятая доля из таких кусков не складывается.
В десятичной записи не кончается 1/3,
в битах так же не кончается 0.1.
В double помещается ближайшее значение
примерно на 15 значащих цифр.
У float цифр около 7, зазор крупнее.
Для 0.1 вывод может выглядеть коротко,
но после действий часто виден хвост:
double num = 0.1;
Console.WriteLine(num); // prints 0.1
Складываются не написанные десятые, а ближайшие
значения из памяти. Сумма 0.1 + 0.2
не равна литералу 0.3, и вывод
показывает длинную десятичную запись:
double num = 0.1 + 0.2;
Console.WriteLine(num); // prints 0.30000000000000004
if (num == 0.3) {
Console.WriteLine("Y");
} else {
Console.WriteLine("N"); // this branch runs
}
Вычитание устроено так же. Разность 0.3 - 0.1
не совпадает с 0.2 в сравнении, а на экране
виден другой хвост:
double num = 0.3 - 0.1;
Console.WriteLine(num); // prints 0.19999999999999998
if (num == 0.2) {
Console.WriteLine("Y");
} else {
Console.WriteLine("N"); // this branch runs
}
Умножение перемножает хранимые значения, а не школьные десятые:
double num = 0.1 * 3.0;
Console.WriteLine(num); // prints 0.30000000000000004
if (num == 0.3) {
Console.WriteLine("Y");
} else {
Console.WriteLine("N"); // this branch runs
}
Зазор виден не в каждом действии. Иногда сумма двух приближенных чисел совпадает с привычным результатом и в памяти. Тогда срабатывает первая ветка:
double num = 0.1 + 0.1;
Console.WriteLine(num); // prints 0.2
if (num == 0.2) {
Console.WriteLine("Y"); // this branch runs
} else {
Console.WriteLine("N");
}
Даны две переменные:
double num1 = 0.1;
double num2 = 0.7;
Найдите сумму и выведите ее.
Если сумма равна 0.8, выведите
"Y", иначе "N".
Даны две переменные:
double num1 = 0.2;
double num2 = 0.1;
Найдите сумму и выведите ее.
Если сумма равна 0.3, выведите
"Y", иначе "N".
Даны две переменные:
double num1 = 0.25;
double num2 = 0.25;
Найдите сумму и выведите ее.
Если сумма равна 0.5, выведите
"Y", иначе "N".
Даны две переменные:
double num1 = 0.3;
double num2 = 0.2;
Найдите разность: вычтите вторую из первой и выведите ее.
Если разность равна 0.1, выведите
"Y", иначе "N".
Даны две переменные:
double num1 = 0.4;
double num2 = 0.1;
Найдите разность: вычтите вторую из первой и выведите ее.
Если разность равна 0.3, выведите
"Y", иначе "N".
Даны две переменные:
double num1 = 0.1;
double num2 = 0.2;
Найдите произведение и выведите его.
Если произведение равно 0.02, выведите
"Y", иначе "N".
Даны две переменные:
double num1 = 0.2;
double num2 = 3.0;
Найдите произведение и выведите его.
Если произведение равно 0.6, выведите
"Y", иначе "N".
Даны две переменные:
double num1 = 0.5;
double num2 = 0.5;
Найдите произведение и выведите его.
Если произведение равно 0.25, выведите
"Y", иначе "N".
Даны три переменные:
double num1 = 0.1;
double num2 = 0.2;
double num3 = 0.3;
Найдите сумму и выведите ее.
Если сумма равна 0.6, выведите
"Y", иначе "N".