Ваша концепция толерантности неправильно устанавливает строгий слабый порядок, поскольку он не является транзитивным. Для примера представьте, что допуск равен 1
. Теперь рассмотрим:
a = 1
b = 2
c = 3
здесь: !(a<b)
и !(b<c)
, но a<c
. Это явное нарушение требования транзитивности для строгого слабого упорядочения.
Если вы хотите реализовать сравнение, которое имеет допуск, но которое также является строгим слабым порядком, вы должны последовательно округлить каждое значение (например, 1.5 => 2
, 0.75 => 1
, 2.3 => 2
и т. д.), а затем сравнить округленные значения.
Делать это кажется очень бессмысленным, так как double
уже делают это, но с максимально возможной точностью. Вы по-прежнему будете вести себя странно, когда обнаружите, что 1.4999999... != 1.5
.
Вы должны просто написать свой компаратор следующим образом и отказаться от концепции допуска:
bool operator<(const Point3D &Pt1, const Point3D &Pt2)
{
//This can be replaced with a member/free function if it is used elsewhere
auto as_tie = [](Point3D const &Pt) {
//assumes the member functions return references
//to the internal `Point3D` values.
return std::tie(Pt.x(), Pt.y(), Pt.z());
};
return as_tie(Pt1) < as_tie(Pt2);
}
Если вы абсолютно должны иметь допуск, округляйте значения, как только они помещаются в Point3D
, или округляйте значения непосредственно перед сравнением (в зависимости от других требований в вашей системе).
person
Mankarse
schedule
09.06.2014
double
и толерантностью? - person nathanael   schedule 09.06.2014