Здравствуйте, WoldemaR, Вы писали:
WR>Лучше так:
WR>WR>#include <limits>
WR>template <typename t1, typename t2>
WR>bool IsEqual(const t1& v1, const t2& v2)
WR>{
WR> return ::abs(v1 - v2) <=
WR> max(std::numeric_limits<t1>::epsilon(),
WR> std::numeric_limits<t2>::epsilon());
WR>};
WR>
Два вопроса:
1. Почему эта проверка относительная?
2. Почему считается, что std::numeric_limits<t2>::epsilon() — это именно та точность, которая нужна?
Уточняю:
1.
два числа 10000000.1 и 10000000.2 почти не отличаются, а 0.100000000001 и 0.200000000001 отличаются примерно в два раза.
Если проверка относительная, то она заметит разницу, а если нет -- то нет
2.
насколько я помню std::numeric_limits<double>::epsilon() -- это самое маленькое double число, которое при добавлении к 1.0 даст результат отличный от 1.0.
В реальных вычислениях ошибки округления больше, так как обычно операций больше одной. Но при этом такая точность обычно бывает избыточной.
Так что нужно задать какой-то уровень относительной точности, или управлять точностью сравнения на равенство в каждом конкретном месте.
Поэтому нужен и третий параметр, и нужно в его значении брать число намного превосходящее эпсилон, а использовать ли для этого шаблоны -- вопрос стиля. Я, например, не очень понимаю, зачем нужен такой шаблон. Какой тип параметра, кроме double есть желание поддержать?
Обычно все вычисления в программе бывают или double или float
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском