使用std :: max来比较两个安全的双打吗?

时间:2015-07-01 02:03:56

标签: c++ c++11

我知道比较两个双打我们必须做这样的事情

bool AreSame(double a, double b)
{
    return fabs(a - b) < EPSILON;
}

但是我不知道std :: max是否以相同的方式比较两个双打,或者如果安全的方式不一样?如果我打电话,这就是答案 std::max(0.1,0.11)。我得到了正确的结果但仍然,我不确定! Morover我昨晚在codeforces上使用它并接受了我的解决方案!

为什么我担心? 我检查http://www.cplusplus.com/如果写的是max的行为与下面的代码相同

template <class T> const T& max (const T& a, const T& b) {
  return (a<b)?b:a;     // or: return comp(a,b)?b:a; for version (2)
}

指向页面Link

的链接

(相对差异为10 ^ -6)

2 个答案:

答案 0 :(得分:3)

std::max并不关心平等,只关心这两个数字不相等。另外,epsilon事物与寻找大致相等的数字有关,其差异是由浮点错误引起的。浮点错误应该导致std::max选择一个,因为std::max无法知道什么是epsilon。

请记住,您的系统可能需要AreSame(0.1000001, 0.1) == true,但std::max(0.1000001, 0.1)应该返回0.1000001,以防您需要照顾。

答案 1 :(得分:3)

(正如你刚刚修改过你的问题)max应该做一个简单的'&lt;',比如

(a < b) ? b : a

这应该是“安全的”,因为你可以在两个双打/浮点数之间进行比较。但是,双精度/浮点数实际上只是值的近似值,它们可能是也可能不是精确值。您可以在基数10中看到这个值,其值为1/3 = .3333 ...写入的十进制值永远不能精确到1/3,因为它是无限重复的值。为了使处理器使用离散值,必须使用有限数量的比特,因此将进行舍入。这使得“等于”的概念有点混乱,你真的说两个值大致相等,给定一些容差(epsilon)足够接近。你可以争辩说&gt;和&lt;也受到这种近似过程的变幻莫测的影响。然而,通常人们愿意接受具有&lt;的两个值的“更广泛”的概念。或者&gt;关系。

实际上这可能是一个非常复杂的问题。这在很大程度上取决于您正在做什么以及您的应用程序对这些数值逼近问题的容忍度。我知道一种情况,其中AI算法受到使用FPU指令到使用MMX / SSE / AVX ...类型指令的影响(PC FPU通常在内部以80位计算然后舍入,而AVX指令使用64位{{ 3}})。在许多迭代的过程中,基于舍入的差异导致采用不同的路径导致不同的结果。这主要与这些类型的比较有关。您不能说该方法(取决于FPU行为)是不正确的,只是它不能容忍“较低分辨率”FP计算的更改。