Сумма 0.1 и 0.2 НЕ равняется 0.3

Странное дело, но это правда — сумма .1 и .2 не будет равняться .3.

Рассмотрим на примере:

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

Результатом подобного сравнения также будет 0. А что если продебажить результат выражения?

Как видим мы получаем в итоге тип float и значение 0.3.

Так в чем же дело? Почему так происходит?

Суть проблемы сравнения состоит в том, что в данном случае мы работаем с числами округляя их до десятых и чтобы видеть картину целиком, давайте округлим до… 17(!)го знака:

Немного странный результат, правда? А все потому, что Вы видите и работате с простыми дробями, но компьютер оперирует двоичными числами. Таким образом перед выполнением выражения он переводит десятичное представление чисел в двоичное — нули и единицы.

Затем следует знать, что при переводе в двоичную систему, некоторые числа имеют бесконечную (либо очень большую) дробь, а так как на хранение чисел выделяется ограниченное кол-во памяти в системе — они окргуляются/обрезаются по стандарту IEEE 754. И вот накопленные округления дают на выходе такие погрешности и как результат — неточность вычисления.

Конкретно в нашем примере проблема с 0.1 — это число не может быть точно представлено в двоичной системе.

Так как сравнить сумму 0.1 + 0.2 с 0.3?

Вариант №1.

Для функции bcadd необходимо добавить библитеку PHP — php7.1-bcmath. В противном случае вы получите ошибку уровня Fatal.

Результат будет типа string!

PHP сам приведет $test к нужному типу данных и в этом случае результатом сравнения будет 1

Вариант №2

Данное выражение также даст нам положительный результат сравнения.