Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗cpPmCdIC 123 of 390 menu
◀ ▶

Неточные вычисления в C++

Дробный счет иногда расходится с обычной арифметикой. На экран сумма выходит привычной, а проверка в if эту привычную дробь не узнает.

В битах дробь собирается из половин, четвертей, восьмых и таких же следующих долей. Если число складывается из этих долей без хвоста, оно лежит в памяти точно. 0.5 - это половина, 0.25 - четверть:

double num = 0.5 + 0.25; std::cout << num << "\n"; // выведет 0.75

Десятая доля из таких кусков не складывается. В десятичной записи не кончается 1/3, в битах так же не кончается 0.1. В double помещается ближайшее значение примерно на 15 значащих цифр. У float цифр около 7, зазор крупнее. На экран 0.1 все равно выходит коротко:

double num = 0.1; std::cout << num << "\n"; // выведет 0.1

Зазор проявляется в действии. Складываются не написанные десятые, а ближайшие значения из байтов. Их сумма не совпадает с тем, как в памяти лежит 0.3. Обычный вывод все равно показывает 0.3. Проверка равенства уходит в другую ветку:

double num = 0.1 + 0.2; std::cout << num << "\n"; // выведет 0.3 if (num == 0.3) { std::cout << "Y" << "\n"; } else { std::cout << "N" << "\n"; // сработает это }

Вычитание устроено так же. Разность может не совпасть с привычной десятой. На экране снова короткая запись, а ветка равенства не срабатывает:

double num = 0.3 - 0.1; std::cout << num << "\n"; // выведет 0.2 if (num == 0.2) { std::cout << "Y" << "\n"; } else { std::cout << "N" << "\n"; // сработает это }

Умножение перемножает хранимые значения, а не школьные десятые:

double num = 0.1 * 3.0; std::cout << num << "\n"; // выведет 0.3 if (num == 0.3) { std::cout << "Y" << "\n"; } else { std::cout << "N" << "\n"; // сработает это }

Зазор виден не в каждом действии. Иногда сумма двух приближенных чисел совпадает с привычным результатом и в памяти. Тогда срабатывает первая ветка:

double num = 0.1 + 0.1; std::cout << num << "\n"; // выведет 0.2 if (num == 0.2) { std::cout << "Y" << "\n"; // сработает это } else { std::cout << "N" << "\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".

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить