Сравнение и округление чисел с плавающей точкой
Сегодня предлагаю разобрать на несложных примерах такие вопросы как сравнение и округление чисел с плавающей точкой. В целом эти задачи очень просты, однако новичкам нужно иметь в виду пару важных моментов, которые мы и рассмотрим.
Сравнение чисел с плавающей точкой
Пусть перед нами стоит вполне тривиальная задача: нам нужно всего лишь проверить, равны ли между собой два числа с плавающей точкой.
Несмотря на примитивность задачи у нее есть определенные подводные камни, избежать которых можно, если произвести сравнение не так, как это обычно делается.
Давайте сначала разберем правильное решение, после чего уже поговорим, почему следует делать именно так, а не иначе.
Итак, для сравнения нам нужно произвольно выбрать некий небольшой интервал (так называемую "дельта") и проверить, превышает ли абсолютная величина разности двух числе указанный нами интервал.
Как это выглядит в коде:
$delta = 0.00001; $a = 1.0000000; $b = 1.0000001; if (abs($a - $b) < $delta) { print '$a и $b можно считать равными с заданной степенью точности'; }
Почему же мы использовали такой неочевидный подход?
Дело в том, что в двоичном представлении чисел с плавающей точкой используется конечное число разрядом мантиcсы и экспоненты и при выходе за пределы разрядности происходит переполнение.
В результате PHP (а также некоторые другие языки) считает, что два равных числа различны, потому что они различаются в конечных разрядах.
Чтобы избежать подобных проблем, вместо проверки $a == $b следует проверить, отличается ли первое число от второго на очень малый интервал ($delta).
Размер интервала определяется минимальной разностью, начиная с которой два числа считаются разными. Как я уже упомянул, это значение мы устанавливаем произвольно, исходя из того, какой точности сравнения хотим добиться.
— Регулярная проверка качества ссылок по более чем 100 показателям и ежедневный пересчет показателей качества проекта.
— Все известные форматы ссылок: арендные ссылки, вечные ссылки, публикации (упоминания, мнения, отзывы, статьи, пресс-релизы).
— SeoHammer покажет, где рост или падение, а также запросы, на которые нужно обратить внимание.
SeoHammer еще предоставляет технологию Буст, она ускоряет продвижение в десятки раз, а первые результаты появляются уже в течение первых 7 дней. Зарегистрироваться и Начать продвижение
Ну и, наконец, для получения абсолютного значения разности мы используем функцию abs().
Округление чисел с плавающей точкой
Теперь давайте посмотрим, как можно округлять числа с плавающей точкой до целого числа или до заданного количества разрядов в дробной части.
Задача эта более, чем популярная, когда нам нужно рассчитать значения рейтингов, величину налогов, размер скидки и т.д.
Округление числа до ближайшего целого выполняется функцией round():
$number = round(2.4); printf ("2.4 округляется до %s", $number);
Результат будет такой:
2.4 округляется до 2
Чтобы округление выполнилось в большую сторону, используйте функцию ceil():
$number = ceil(2.4); printf ("2.4 округляется вверх до %s", $number);
Результат будет таким:
2.4 округляется вверх до 3
Округление в меньшую сторону осуществляется с помощью функции floor():
$number = floor(2.4); printf ("2.4 округляется вниз до %s", $number);
Результат:
2.4 округляется вниз до 2
Отлично, с базовыми вещами разобралась. Теперь давайте рассмотрим некоторые частные моменты.
Если число находится ровно посередине между двумя числами, PHP округляет его в направлении от 0:
$number = round(2.5); printf ("Округление положительного числа идет вверх до %s", $number); echo "<br>"; $number = round(-2.5); printf ("Округление отрицательного числа идет вниз до %s", $number);
Результат выполнения этого кода будет следующий:
Округление положительного числа идет вверх до 3 Округление отрицательного числа идет вниз до -3
Еще один существенный момент, который нужно понимать, заключается в том, что числа с плавающей точкой не всегда представляют точные значения, что связано с особенностями их хранения в компьютере. Иногда такие погрешности создают путаницу.
Значение, которое на первый взгляд имеет дробную часть ".5", вместо этого может иметь дробную часть ".499999...9" (с длинной последовательностью девяток) или ".5000000...1" (с множеством нулей и завершающей единицей).
PHP автоматически включает небольшой "разброс" в вычислении с округлением, так что вам об этом беспокоиться не придется.
Для округления до заданного количества знаков в дробной части функция round() может получать необязательный аргумент. Допустим, вы вычисляете суммарную цену товаров в корзине покупателя:
$cart = 54.23; $tax = $cart * .05; $total = $cart + $tax; $final = round($total,2); print "При подсчете суммы налога используются все разряды: $total, но функция round() обрезает их до 2 знаков после целого числа: $final";
Результат будет таким:
При подсчете суммы налога используются все разряды: 56.9415, но функция round() обрезает их до 2 знаков после целого числа: 56.94
Для округления числа в меньшую сторону используется функция floor():
$number1 = floor(2.1); // floor(2.1) дает 2.0 $number2 = floor(2.9); // floor(2.9) тоже дает 2.0 $number3 = floor(-2.1); // floor(-2.1) дает -3.0 $number4 = floor(-2.9); // floor(-2.9) тоже дает -3.0
Для округления числа в большую сторону используется функция ceil():
$number1 = ceil(2.1); // ceil(2.1) дает 3.0 $number2 = ceil(2.9); // ceil(2.9) тоже дает 3.0 $number3 = ceil(-2.1); // ceil(-2.1) дает -2.0 $number4 = ceil(-2.9); // ceil(-2.9) тоже дает -2.0
За сим заканчиваю данную заметку и надеюсь, что парочку полезных моментов вы для себя из нее вынесли.
Успехов вам, и до связи!
Понравился материал и хотите отблагодарить?
Просто поделитесь с друзьями и коллегами!
Смотрите также:
PHP: Получение информации об объекте или классе, методах, свойствах и наследовании |
|
Функции обратного вызова, анонимные функции и механизм замыканий |
|
Применение функции к каждому элементу массива Сервис онлайн-записи на собственном Telegram-боте
Попробуйте сервис онлайн-записи VisitTime на основе вашего собственного Telegram-бота:— Разгрузит мастера, специалиста или компанию; — Позволит гибко управлять расписанием и загрузкой; — Разошлет оповещения о новых услугах или акциях; — Позволит принять оплату на карту/кошелек/счет; — Позволит записываться на групповые и персональные посещения; — Поможет получить от клиента отзывы о визите к вам; — Включает в себя сервис чаевых. Для новых пользователей первый месяц бесплатно. Зарегистрироваться в сервисе |
|
Деструктор и копирование объектов с помощью метода __clone() |
|
Эволюция веб-разработчика или Почему фреймворк - это хорошо? |
|
Магические методы в PHP или методы-перехватчики (сеттеры, геттеры и др.) |
|
50 классных сервисов, программ и сайтов для веб-разработчиков |