Ошибки округления в программировании

136 прочитали

Я уже рассказывал про возможные неожиданности при сравнении вещественных чисел. Правда, не на этой площадке. Но ссылка есть, можете почитать. Сегодня продолжу тему и расскажу про округление. Хотя в той же статье по ссылке я об этом говорил, здесь немного дополню.

Современные процессоры достаточно умны и часто правильно обрабатывают ошибки округления.

Если, например, вы разделите 10 на 3, а потом результат снова умножите на 3, то на современных компьютерах, скорее всего, вы получите 10. То есть вот такой код:

float x;
float z;
x = 10.0 / 3.0;
z = x * 3.0;
cout << z << endl;

выведет на экран число 10 (пример на языке С++). Но на старых компьютерах это может быть и не так. Например, вы можете в результате получить 9.9999. Это и называется ошибкой округления. Да и на современных компьютерах это в некоторых случаях тоже может случиться.

Особенно осторожно надо использовать вещественные числа в операциях сравнения. Например, вот такой код:

float x;
float z;
x = 10.0 / 3.0;
z = x * 3.0; //z = 10
z = z / 3.0;
cout << (x == z) << endl;

Выведет на экран 1 (то есть выражение (x == z) истинно), и результат ожидаемый. Но если мы сделаем так:

float x;
float z;
x = 10.0 / 3.0;
z = x * 3.0;
cout << (x == (z / 3.0)) << endl;

то на экран будет уже выведено 0. Хотя вроде как с математической точки зрения ничего не изменилось и мы ожидали получить 1. Но здесь уже вмешалась ошибка округления, которую процессор не смог обработать.

Кстати, ранее я рассказывал, как выводить на консоль логические значения в виде слов, а не цифр.

А что если мы сделаем то же самое в Python?

Я уже рассказывал про возможные неожиданности при сравнении вещественных чисел. Правда, не на этой площадке. Но ссылка есть, можете почитать. Сегодня продолжу тему и расскажу про округление.

О как! Здесь всё в порядке! Неужели Python круче, чем С++? Да нет, конечно. Тем более, что он написан на С/С++. Просто Python автоматически определяет тип переменных и подбирает наиболее подходящий. Если мы в С++ заменим тип float на double, то также получим правильный результат:

double x;
double z;
x = 10.0 / 3.0;
z = x * 3.0;
//Выведет 1
cout << (x == (z / 3.0)) << endl;

Однако на это уповать не стоит. Лучше перестраховаться и использовать какой-либо из способов сравнения вещественных чисел.

На этом всё. Подписывайтесь на канал, чтобы ничего не пропустить.