Причина в том, что числа с плавающей запятой не являются реальным представлением числа, которое вы сохраняете в переменной. (В противоположность BCD [двоично-десятичные десятичные числа])
Вы можете увидеть определение здесь:
Плавающая точка Википедия
Таким образом, проблема в том, что определенные числа не могут быть выражены с заданным набором битов. (Вы могли бы, если бы вы могли добавлять биты бесконечно)
Хитрость в том, что в большинстве случаев разница между сохраненным номером и предполагаемым числом довольно мала. На практике у вас есть несколько угловых случаев, когда это может привести к проблемам.
Это, например, причина, по которой вам не следует создавать финансовое программное обеспечение и использовать числа с плавающей запятой для расчета денег. Вы можете легко заметить различия, которые не понравятся вашей налоговой инспекции.
Таким образом, для сравнения чисел с плавающей запятой вы всегда должны применять какой-то порог, который подходит для вашего приложения. Что-то вроде:
if(a==b)
становится
if(abs(a-b)<threshold)
Редактировать: Как отметил Дэвид в своем комментарии, у вас все еще будут проблемы с такими вещами, как пи, 1./3., ...
Но вы можете, по крайней мере, хранить цифры без потери точности, которые вы положили в систему. Поскольку у компьютеров ограниченная память, вы всегда можете построить угловые случаи, когда вы не можете полагаться на точное представление ...
Только что видел ваше редактирование текста, поэтому вот следующее редактирование:
if(a<1)
Как-то сложнее, потому что вы не знаете, является ли неправильным только представление чисел или просто реальное значение, близкое к 1. Это действительно зависит от требований вашего алгоритма. Если небольшая ошибка в порядке, тогда выполните:
if(a < 1-threshold)
Если это не нормально, тогда вам нужно использовать другой тип переменной, который не страдает от проблемы.