Вы сталкиваетесь с ограничением арифметики с плавающей запятой. Точно так же, как есть определенные числа, которые вы не можете представить точно в десятичном виде (например, 1/3), есть некоторые числа, которые вы не можете точно представить в двоичном виде с плавающей запятой.
Никогда не пытайтесь сравнивать числа с плавающей запятой на равенство, поскольку ограничения с плавающей запятой делают маловероятным, чтобы сравниваемые переменные имели действительное значение, которое точно соответствует значению, которое, по вашему мнению, они имеют. Вам необходимо добавить «коэффициент выдумки», то есть, если два числа похожи в пределах определенного допуска, то вы должны считать их равными.
Вы можете сделать это, вычтя одно число из другого и увидев, что абсолютный результат ниже вашего порога (в моем примере 0,01):
if (abs ($someFloatingPointNumber - $someOtherFloatingPointNumber) <= 0.01)
{
// The values are close enough to be considered equal
}
Конечно, это в сочетании с ошибками округления, которые могут появиться при последовательных математических операциях, означают, что числа с плавающей запятой часто не всегда являются лучшим выбором, и их следует избегать, где это возможно. Например, если вы имеете дело с валютой, сохраняйте значения в виде целых чисел в младшей единице (пенни за фунты стерлингов, центы за доллары США и т. Д.) И конвертируйте их только в основную единицу, разделив на 100 для отображения.