whitefoxИмхо, достаточно (x == 0)
Смотря с какой стороны посмотреть. С точки зрения корректности программы
достаточно. С точки зрения хорошего стиля кодирования лучше избегать неявного преобразования типов для констант, т.е. объявлять константы того типа, который подразумевается по логике работы программы. А именно:
0.0 double,
0.0f float,
0.0L long double,
0 int,
0L long и т.д. В данном случае число типа
double сравнивается с константой, которую лучше объявить как константу типа
double 0.0.
binИМХО все сравнения на равенство для чисел с плавающей запятой вне зависимости от применяемого языка осуществляются по формуле
, т.о. ИМХО нужно выбрать точность
в зависимости от применяемого формата
doubleЭто неправильно, как мне кажется. Даже безотносительно того, что в каких-то особенно редких случаях может потребоваться прямое сравнение на равенство. Прежде всего,
должно зависеть не только от применяемого формата, но и от характерных величин сравниваемых значений. Т.е. в общем случае лучше использовать не абсолютную, а относительную погрешность:
К сожалению, такой подход нельзя распространить на весь диапазон "компьютерных" вещественных чисел, при приближении сравниваемых чисел к нулю с ним начинаются проблемы (2 ближайших к нулю числа одного знака дадут значение погрешности
, разных знаков
аж
). Поэтому близкие к нулю числа лучше сравнивать все-таки с использованием абсолютной погрешности:
. Эти две области сравнения надо как-то сопрячь. В самом простом случае можно взять некое "граничное" число
. Если
, то использовать для сравнения абсолютную погрешность. В противном случае
относительную. При этом предварительно нужно проверить некоторые особые варианты (NaN'ы, бесконечности). Таким образом, процедура сравнения будет зависеть от двух вспомогательных параметров (
и
), которые нужно либо заранее знать (основываясь на некой предварительной информации о порядках сравниваемых величин), либо вычислять в процессе выполнения программы на основе полученных ею данных.
Помимо такого "универсального" способа сравнения вещественных чисел есть принципиально иной механизм. Он основывается на интересной особенности стандарта IEEE 754, благодаря которой арифметический порядок вещественных чисел соответствует лексикографическому порядку их битовых представлений (для любых вещественных чисел, включая бесконечности и исключая NaN'ы и нули,
, где
и
целочисленные интерпретации битовых представлений вещественных чисел
и
). В данном случае при сравнении чисел задается только один (целочисленный) параметр
наибольшее допустимое количество
ульпов между сравниваемыми числами. Для нормализованных чисел это равносильно заданию относительной погрешности, а для денормализованных
абсолютной. Но, в отличие от предыдущего метода, сравнение (даже с учетом дополнительных нюансов) производится значительно быстрее.
Yuri GendelmanВ качестве платформозависимой оценки
иногда рекомендуется максимальное
такое, что
.
Это как в преферансе: "Хода нет - ходи с бубей".
Но ведь такое сравнение заведомо бессмысленно для чисел, больших единицы (или двух, если используется другое машинное эпсилон) по абсолютной величине.
SkepticПри делении на 0 система выдаст ошибку с определённым кодом.
Какую систему Вы имеете в виду? Обычно при делении (отличного от нуля) числа на нуль получается бесконечность.