#cpp #float #сравнение #double
Как правильно сравнивать два числа типа float и double? Следующий способ часто говорит, что одинаковые числа различны: float a = 0.00001001; double b = 0.00001001; if (a == b) { std::cout << "equal"; // не выводит equal } Мой вопрос отличается от дубликатов тем, что мне нужно знать, как правильно сравнить 2 числа типа float и double на C++, а не почему (не только почему) простое сравнение не работает. В привидённых в дубликатах ответах либо ответы для 2 одинаковых типов, либо не сказано как выбирать epsilon и т.д..
Ответы
Ответ 1
if (fabs(a - b) <= eps) где eps - некая маленькая величина, вообще говоря - зависящая от порядка самих чисел, поэтому более корректно if (fabs(a - b)/ max(fabs(a) + eps, fabs(b) + eps) <= eps) Пример задания eps: const FuzzFactor = 1000; SingleResolutionEps = 1E-7 * FuzzFactor; DoubleResolutionEps = 1E-15 * FuzzFactor; Откуда это берётся - точность float 23 двоичных разряда или 7-8 десятичных, т.е. число имеет 7 верных десятичных цифр, поэтому меньше 1E-7 eps смысла нет делать. Почему используется множитель FuzzFactor = 1000; - это расширение допуска, чёткого критерия его выбора нет, разработчики этой библиотеки решили так сделать, а вообще множитель можно выбирать в зависимости от желаемой погрешности в младших разрядах. Для сравнения float и double по правилам сложения погрешностей следует использовать погрешность для менее точных float, т.е. порядка 1E-7 даже при приведении float к double, как предложил в комментарии @Grundy - ведь при этом приведении возникают дополнительные ничем не обеспеченные разряды с погрешностью в пределах всё тех же 1E-7. Труды по точности float-арифметики: 1 2 GoldbergОтвет 2
Машинный эпсилон это одно,а точность входных данных в задаче это совсем другое. Редко бывает, чтобы точность входных данных в задаче была равна машинному эпсилону. Обычно точность входных данных в задаче гораздо меньше, чем машинный эпсилон. Есть целая наука об правилах округления и отбрасывания незначащих цифр. Исходя из этой науки и выбирается в каждом конкретном случае эпсилон для каждой конкретной задачи. А машинный эпсилон это характеристика данной вычислительной системы.
Комментариев нет:
Отправить комментарий