简体   繁体   English

使用std :: max比较两个双打是否安全?

[英]Is using std::max for comparing two doubles safe?

I know for comparing two doubles we have to do something like this 我知道要比较两个双打,我们必须做这样的事情

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

But I do not know that does std::max compares two doubles the same way or if not the same way safely? 但是我不知道std :: max是否以相同的方式比较两个双精度值,或者是否以相同的方式安全比较? That is what will be the answer if I call std::max(0.1,0.11) . 如果我调用std::max(0.1,0.11)那将是答案。 I am getting right results but still , I am not sure! 我得到了正确的结果,但是仍然不确定! Morover I used it last night at codeforces and got my solution accepted! Morover我昨晚在codeforces上使用了它,并接受了我的解决方案!

Why am I worried? 我为什么担心? I checked http://www.cplusplus.com/ were it was written that the behaviour of max is same as the following code 我检查了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)
}

The link to page Link 页面链接

(The relative difference being 10^-6) (相对差为10 ^ -6)

std::max isn't concerned with equality, it only cares when the two numbers are not equal. std::max不关心相等性,它只关心两个数字不相等时的情况。 Additionally the epsilon thing is related to looking for approximately equal numbers whose difference is caused by floating point errors. 另外,ε问题与寻找近似相等的数字有关,其差是由浮点误差引起的。 Floating point errors should cause std::max to pick one over the other as std::max has no way of knowing what epsilon would be appropriate. 浮点错误应导致std::max选择另一个作为std::max因为std::max无法知道哪种epsilon是合适的。

Remember your system may want AreSame(0.1000001, 0.1) == true but std::max(0.1000001, 0.1) should return 0.1000001 in case you do care. 请记住,您的系统可能希望AreSame(0.1000001, 0.1) == truestd::max(0.1000001, 0.1)应该返回0.1000001 ,以防万一。

(as you just amended to your question) max should be doing a simple '<', like (正如您刚刚修改的问题一样)max应该做一个简单的“ <”,例如

(a < b) ? b : a

This should be "safe" in that you can do a comparison between two doubles/floats. 这应该是“安全的”,因为您可以在两个双打/浮点数之间进行比较。 However, doubles/floats are really just approximations for values, they may or may not be the exact value. 但是,双精度数/浮点数实际上只是值的近似值,它们可能是也可能不是确切值。 You can see this in base 10 with a value like 1/3 = .3333... the written decimal value can never be exact 1/3 because it is an infinitely repeating value. 您可以在以10为基数的值中看到一个类似1/3 = .3333的值...写入的十进制值永远不可能是精确的1/3,因为它是一个无限重复的值。 In order for the processor to work with discrete values a limited number of bits must be used, therefore rounding will occur. 为了使处理器能够使用离散值,必须使用有限数量的位,因此将发生舍入。 This makes the concept of "equals" a bit muddy, really are you saying two values are approximately equal, close enough given some tolerance (epsilon). 这使“等于”的概念有些混乱,您实际上是在说两个值近似相等,在给定一定的公差(ε)的情况下足够接近。 You can argue that > and < are also effected by the vagaries of this approximation process. 您可以认为>和<也受此近似过程的变化影响。 However, generally people are willing to accept the "broader" idea of two values having a < or > relationship. 但是,通常人们愿意接受具有<或>关系的两个值的“更广泛”的想法。

It can actually be a quite complicated question. 实际上这可能是一个非常复杂的问题。 It depends largely on what you are doing and the sort of tolerance your application has to these numeric approximation issues. 这在很大程度上取决于您的工作以及您的应用程序对这些数值近似问题的容忍程度。 I know of one case where an AI algorithm was affected by a change from using FPU instructions to using MMX/SSE/AVX... type instructions (PC FPUs generally calculate internally at 80 bits then round, while AVX instructions use 64 bits stem to stern ). 我知道一种情况的AI算法使用FPU的指令使用MMX / SSE / AVX ...类型的指令(PC的FPU通常在80位内部计算然后圆形,而AVX指令使用64位受变化的干至船尾 )。 Over the course of many iterations differences based on rounding caused different paths to be taken leading to different results. 在许多迭代过程中,基于舍入的差异导致采用不同的路径导致不同的结果。 This largely had to do with these types of comparisons. 这很大程度上与这些类型的比较有关。 You can't say that the approach (depending on FPU behavior) was incorrect, only that it wasn't tolerant of changes to a "lower resolution" FP calculation. 您不能说这种方法(取决于FPU行为)是不正确的,只是不能容忍对“较低分辨率” FP计算的更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM