Иногда, когда работаешь с дробными числами в php можно получить неожиданные результаты и складывается впечатление, что php неправильно округляет в большую или меньшую сторону числа с плавающей точкой. Вот пример некорректного округления в меньшую сторону функцией floor:
$a = 0.1; $b = 0.7; echo floor(($a + $b) * 10); // выведет 7 вместо ожидаемого 8
Или вот еще один пример неправильного округления функцией ceil:
$a = 33.7; echo ceil($a * 100); // выводит 3371 вместо ожидаемого 3370
На самом деле все дело не в округлении, а в том, как php хранит в памяти числа с плавающей точкой. Казалось бы вполне точное число, например, 0.8 на самом деле в памяти может быть числом 0.7999999999...
Есть 2 варианта как можно выйти из положения.
1-й способ
Преобразовывать числа в строку и выполнять "вручную" действия деления, умножения, сложения, вычитания и т.д. Не буду останавливаться на этом варианте, т.к. написание такой программы будет трудоемко и на мой взгляд малоэффективно, а вот второй способ гораздо лучше и правильнее.
2-й способ
Использовать функции BC Math, которые поддерживают числа любого размера и точности. Приведу их перечень:
- bcadd — Сложить 2 числа произвольной точности
- bccomp — Сравнение двух чисел произвольной точности
- bcdiv — Операция деления для чисел произвольной точности
- bcmod — Получает остаток от деления чисел с произвольной точностью
- bcmul — Умножение двух чисел с произвольной точностью
- bcpow — Возведение в степень чисел с произвольной точностью
- bcpowmod — Возводит одно число в степень другого и возвращает остаток от деления результата на третье число
- bcscale — Задает количество чисел после десятичной точки по умолчанию для всех bc math функций.
- bcsqrt — Извлекает квадратный корень из числа с заданной точностью
- bcsub — Вычитает одно число из другого с заданной точностью
Подробнее с этими функциями можно познакомиться на php.net
Комментарии к статье:
Добавить комментарий: