0

我想尽可能有效地比较两个包含双精度的元组。

由于浮点精度无法通过使用预定义的 operator==(...) 来完成,那么最好的方法是什么?我是否真的需要遍历所有元组元素,或者是否有一些我可以使用的模板魔法,这可能允许编译器调用一些 SIMD 优化?

4

2 回答 2

6

比较浮点值是否相等是一种误解。在任何没有被严重破坏的实现中,当且仅当比较的值相等时,比较浮点值是否相等才会返回 true。

任何实际错误都存在于您的计算中。这些错误必须得到控制和表征。如果没有对错误进行表征,就不可能就执行哪些适合您的目的的操作提出任何建议。

如果您的值计算不准确,因此它们可能包含一些错误,并且您希望接受实际上不相等的相等值,那么您必须说明 (a) 接受相等的标准,和 (b) 标准因为拒绝平等。说明这些标准后,人们可能会向您提供有关实施满足这两个标准的测试的建议。请注意,(b)和(a)一样重要,因为您通常不希望接受实际上不相等的相等值。由于您的计算中存在错误,因此某些决定将是错误的,您必须确定标准 (a) 和 (b),以便您的应用程序可以接受不正确的决定。重要的是 (a) 和 (b) 不能重叠,否则会出现无法接受任何决定的情况。

在您的情况下,除了从文件中读取数据之外,您没有声明任何错误来源。如果文件中的数据是由优秀软件编写的浮点计算的结果(将浮点值正确转换为具有足够精度的十进制数字),并且您使用良好的软件读取它(将十进制数字正确转换为浮点数)点值),那么在数据的往返过程中没有错误,您应该简单地测试是否相等而没有任何修饰。

于 2012-11-28T14:03:33.453 回答
0

好的,基于我为元组创建的 operator== () 的 STL 实现,它允许我对某些类型使用我想要的任何比较函数:

template<class T>
bool
tupleEqualHelper (const T& lhs, const T& rhs)
{
  return lhs == rhs;
}

template<>
bool tupleEqualHelper<double> (const double& lhs, const double& rhs)
{
 return return (fabs (lhs - rhs) < (std::numeric_limits<double>::epsilon () * 100));
}

template<counter_t i, counter_t j, class T>
struct compareHelper;

template<counter_t i, counter_t j, class T>
struct compareHelper
{
  static bool tupleEqual (const T& lhs, const T & rhs)
  {
    return tupleEqualHelper (std::get<i > (lhs), std::get<i > (rhs)) &&
            compareHelper < i + 1, j, T>::tupleEqual (lhs, rhs);
  }
};

template<counter_t i, class T>
struct compareHelper<i, i, T>
{
  static bool tupleEqual (const T&, const T&)
  {
    return true;
  }
};

template<class ... TTypes>
bool
compareTuple (const std::tuple<TTypes...>& lhs, const std::tuple<TTypes...>& rhs)
{
  typedef std::tuple < TTypes...> Tp;

  return compareHelper < 0, std::tuple_size<Tp>::value, Tp>::tupleEqual (lhs, rhs);
}
于 2012-11-29T13:24:48.800 回答