Начинающие программисты неизбежно столкнутся с проблемами при сравнении вещественных чисел. Потому как с представлением таких чисел в памяти компьютера всё непросто, и вы можете с удивлением узнать, что 10 не равно 10. Поэтому при сравнивании вещественных чисел надо понимать, что вы делаете. Причины этих неприятностей и один из способов сравнения вещественных чисел можно найти здесь. А сегодня расскажу о другом.
Расскажу на примере языка РНР, хотя это справедливо для любых языков. Просто РНР мне волей-неволей приходится использовать, поэтому я его по мере возможности изучаю и делюсь некоторым познаниями. Правда, в РНР и других подобных языках, где не надо указывать тип переменных, указанная проблема может встречаться редко, поскольку по умолчанию используется самый большой тип данных с наивысшей точностью. Но в этом и засада, потому что может случиться ситуация, когда вы “1000 раз так делали”, а на 1001 что-то пойдёт не так.
Например, такой код на РНР:
$x = 10.0;
$y = $x / 3.0;
if ($x == ($y * 3.0))
echo $x, ' = ', $y * 3.0;
else
echo $x, ' НЕ РАВНО ', $y * 3.0;
может вывести ожидаемое значение “10 = 10”, в отличие от примера на Паскале, ссылка на который дана выше. Однако расслабляться не стоит. Потому что в другом похожем случае всё может быть хуже. Например, даже современный РНР мы можем заставить ошибиться, если используем очень большое число:
Правда, здесь я не могу однозначно утверждать, чем вызвана ошибка сравнения - недостаточной точностью или переполнением. Но, тем не менее, если мы сделаем так:
то получим ожидаемый результат. Из этого можно сделать вывод, что проблема всё-таки связана с точностью. Так что при сравнении вещественных чисел желательно всё-таки перестраховываться. И, думаю, вы уже догадались, что это и есть способ сравнения:
- Каждое из сравниваемых чисел мы умножаем на 10
- Результат преобразуем в целые числа с помощью функции intval
- Сравниваем целые числа
Конечно, при преобразовании теряется и точность. Но всё же лучше потерять точность, чем получить труднонаходимые глюки в программе. Для повышения точности можно выполнять умножение не на 10, а, например, на 100 или 1000. Но при этом надо помнить, что так можно выйти из допустимого диапазона, и это тоже приведёт к ошибке сравнения.
На этом всё. Подписывайтесь на канал, чтобы ничего не пропустить.