Как уже упоминали другие, это связано с ограниченной точностью чисел с плавающей запятой в компьютерах. Эти неточности обнаруживаются везде, где принимается жесткое решение «да / нет» относительно числа с плавающей запятой. Чтобы решить проблему, вы можете добавить / вычесть небольшое число, чтобы найти правильный ответ с определенной точностью.
Вы можете найти такие функции, как эти:
#define ACC 1e-7
double floorAcc( double x ) { return floor(x + ACC);}
double ceilAcc( double x ) { return ceil(x - ACC); }
bool isLessThanAcc( double x, double y ) { return (x + ACC) < y; }
bool isEqualAcc( double x, double y ) { return (x + ACC) > y && (x - ACC) < y; }
Конечно, они работают только в ограниченном диапазоне номеров. При работе с очень маленькими или очень большими числами вам нужно выбрать другое значение для ACC.
Обратите внимание, что значение ACC, как правило, зависит от точности чисел в вашем приложении, не от значения x. Например, сравнить два числа a
и b
на равенство можно двумя способами: isEqualAcc(a, b)
и isEqualAcc(a-b, 0)
. Вы хотели бы получить один и тот же результат в обоих случаях, хотя во втором случае число x, вероятно, намного меньше.