1

PHP Version 5.3.3-7+squeeze19

echo round( 8.798768979, 2 );
Результат: 8.800000000000001

echo round( 8.449999999999999, 2 );
Результат: 8.449999999999999

Почему не происходит округление до двух знаков?

Kromster
  • 13,809
  • результат округления тоже дробное число? Дальше https://ru.stackoverflow.com/questions/417453/%d0%92%d1%8b%d1%87%d0%b8%d1%81%d0%bb%d0%b5%d0%bd%d0%b8%d1%8f-%d0%bd%d0%b0-%d1%87%d0%b8%d1%81%d0%bb%d0%b0%d1%85-%d1%81-%d0%bf%d0%bb%d0%b0%d0%b2%d0%b0%d1%8e%d1%89%d0%b5%d0%b9-%d1%82%d0%be%d1%87%d0%ba%d0%be%d0%b9-%d0%bd%d0%b5-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d0%b0%d1%8e%d1%82?s=1|1.0674 – pavel Aug 21 '17 at 06:39
  • Неправда. http://sandbox.onlinephpfunctions.com/code/a4b2788dca23dceeb5d3003964e18cb9e3ecec71 всё он округляет. дайте пруф, что это не так – Алексей Шиманский Aug 21 '17 at 06:41
  • @pavel думаю в связи с этим round гарантирует, что этого безобразия не будет. кмк, скорее всего проблема в другом – Алексей Шиманский Aug 21 '17 at 06:44
  • @АлексейШиманский нет, round этого не гарантирует. Корень проблемы именно в особенностях типа float – rjhdby Aug 21 '17 at 07:33
  • http://php.net/manual/ru/language.types.float.php – rjhdby Aug 21 '17 at 07:34
  • @rjhdby обычно проблемы возникают при сравнивании таких чисел и обычно в таких случая советуют как раз округлять и сравнивать (+ использовать точные типы). Кто может привести действительно воспроизводимый пример с round? у меня не получается. – Алексей Шиманский Aug 21 '17 at 07:50
  • Запустил ваш пример. Получил 8.8 и 8.45. PHP 5.6 – Mrak Aug 21 '17 at 08:30

1 Answers1

2

Это есть не что иное, как погрешность числа с плавающей точкой.

Данная проблема возникает потому, что числа показанные Вами невозможно точно записать в двоичном виде. Плюс, числа с плавающей точкой всегда имеют погрешность, которую вы и наблюдаете.

Подробнее про природу чисел с плавающей точкой вы можете прочитать по следующим ссыкам:

https://www.php.net/manual/ru/language.types.float.php

https://habr.com/ru/post/337260/

https://habr.com/ru/company/xakep/blog/257897/

UPD: нашёл очень забавный сайт, посвещённый этой проблеме

https://0.30000000000000004.com/

Англоязычный StackOverflow советует для получения именно числа с двумя знаками после запятой использовать функцию number_format():

$foo = "105";
echo number_format((float)$foo, 2, '.', '');  // Outputs -> 105.00