Знал что тип float не точен, но первый раз столкнулся с этим недавно. Рассмотрим пример:
<?php
$var1 = 0.3;
$var2 = 0.2 + 0.1;
var_dump($var1 === $var2); // bool(false)
Так происходит потому, что числа с плавающей точкой имеют ограниченную точность. Следующий пример показывает наглядно:
<?php
$var1 = 0.3;
$var2 = 0.2 + 0.1;
echo number_format($var1, 20); // 0.29999999999999998890
echo number_format($var2, 20); // 0.30000000000000004441
После арифметических операций можно округлить результат, но я все равно не рекомендую проверять равенство у типа float:
<?php
$var1 = 0.3;
$var2 = round(0.2 + 0.1, 1);
echo number_format($var1, 20); // 0.29999999999999998890
echo number_format($var2, 20); // 0.29999999999999998890
var_dump($var1 === $var2); // bool(true)
Для сравнения чисел с плавающей точкой в PHP лучше использовать функцию bccomp.
Функция bccomp
bccomp(string $left_operand, string $right_operand [, int $scale = 0 ]): int
Параметры
- $left_operand — левый операнд в виде строки
- $right_operand — правый операнд в виде строки
- $scale — необязательный аргумент scale задает количество цифр после десятичной точки, которое будет участвовать в сравнении
Возвращаемые значения
- 0 — значения $left_operand и $right_operand равны
- 1 — значение $left_operand больше чем $right_operand
- -1 — значение $left_operand меньше чем $right_operand
Пример:
<?php
$var1 = 0.3;
$var2 = 0.2 + 0.1;
var_dump(bccomp($var1, $var2, 1)); // int(0)