Я отвечу чуть более развёрнуто.
Дело в том, что float хранит дробные числа в двоичном формате.
Кроме двоичных мы работаем с десятичными числами и тут возникает проблема.
К примеру, число 1/3 (одна третья) в десятичной системе счисления будет записываться как бесконечная (периодическая) десятичная дробь 0.33333(3). А вот в троичной системе счисления это число запишется конечной троичной дробью: 0.1 (читается, как "ноль целых и одна третья").
По такой же схеме у нас десятичное число 0.5 (ноль целых и пять десятых) равно в двоичной 0.1 (ноль целых и одна вторая). 0.25 [10] == 0.01 [2]; 0.75 [10] == 0.5 [10] + 0.25 [10] == 0.11 [2].
А теперь, внимание, на десятичное число 0.2 (ноль целых и две десятых), для перевода в двоичную систему счисления нам нужно сложить это число из членов двоичного ряда:
==1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128, 1/256, 1/512, 1/1024 ...
0. 0 0 1 1 0 0 ( 1 1 0 0 )
В круглых скобках обозначен период двоичной дроби. То есть двоичной дробью в конечном количестве знаков после двоичной запятой задать десятичное число 0.2 (ноль целых и две десятых) НЕЛЬЗЯ!
Если у нас есть лишь конечное количество знаков, то ими представить в точности 2/10 в двоичной системе счисления одним числом невозможно.
Чему конкретно получится равным "обрзанное" (округлённое конечно) число будет зависеть от того по какой именно двоичный разряд мы его округлили.
Из всего этого следует, что сравнивать записанные таким образом числа на строгое равенство - плохая идея. На самом деле сравнивать на неравенство тоже так себе. Сравнение должно быть с некоторой точностью и точность эту нужно адекватно контролировать.
Итак, чтобы сравнить два числа на равенство, скажем
a и
b, нужно выбрать некое
e=0.0000001
, которое будет определять точность сравнения и проверять условие:
abs(a-b)<e
- модуль разности сравниваемых чисел должен быть меньше выбранной точности. Если условие соблюдается, то числа считаем условно равными с заданной точностью. Если нет - не равными.
Добавлю, что, как отметили выше, цены и денежные суммы вообще в формате с плавающей точкой хранить "плохая примета"=). Для этого есть специальные форматы, которые не создают таких сюрпризов при переводе из/в десятичную систему.
Вот замечательная статья на хабре про это:
Потеря точности из Double во Float или «Куда пропа...
Ну и еще есть:
Что нужно знать про арифметику с плавающей запятой,
Наглядное объяснение чисел с плавающей запятой,
Разбираемся в числах с плавающей точкой, и т.д.