Как правильно сравнивать два числа типа float
и double
? Следующий способ часто говорит, что одинаковые числа различны:
float a = 0.00001001;
double b = 0.00001001;
if (a == b) {
std::cout << "equal"; // не выводит equal
}
Мой вопрос отличается от дубликатов тем, что мне нужно знать, как правильно сравнить 2 числа типа float
и double
на C++, а не почему (не только почему) простое сравнение не работает. В привидённых в дубликатах ответах либо ответы для 2 одинаковых типов, либо не сказано как выбирать epsilon
и т.д..
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
Машинный эпсилон это одно,а точность входных данных в задаче это совсем другое.
Редко бывает, чтобы точность входных данных в задаче была равна машинному эпсилону.
Обычно точность входных данных в задаче гораздо меньше, чем машинный эпсилон.
Есть целая наука об правилах округления и отбрасывания незначащих цифр.
Исходя из этой науки и выбирается в каждом конкретном случае эпсилон для каждой конкретной задачи.
А машинный эпсилон это характеристика данной вычислительной системы.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Есть ли в GCC аналог microsoft'овских property https://msdnmicrosoft
Столкнулся с ошибкой:
У меня задача: есть некое изображение, на котором надо выделить прямоугольную рамку и на выходе получить координаты левой верхней и правой...
Хочу настроить swagger для документирования REST-сервиса на spring bootСледую гайду на этом сайте