正在使用std::max来比较两个替身是否安全
Is using std::max for comparing two doubles safe?
我知道要比较两个双打,我们必须做这样的
bool AreSame(double a, double b)
{
return fabs(a - b) < EPSILON;
}
但我不知道std::max是否以相同的方式比较两倍?如果我打电话给你,那就是答案CCD_ 1。我得到了正确的结果,但我仍然不确定!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)
}
页面链接
(相对差异为10^-6)
(正如您刚才对问题所做的修改)max应该做一个简单的'<',像
(a < b) ? b : a
这应该是"安全的",因为你可以在两个双打/浮动之间进行比较。然而,doubles/float实际上只是值的近似值,它们可能是也可能不是确切的值。你可以在10进制中看到,它的值是1/3=.3333……写入的十进制值永远不可能是精确的1/3,因为它是一个无限重复的值。为了使处理器使用离散值,必须使用有限数量的位,因此将进行舍入。这使得"相等"的概念有点模糊,实际上你是说两个值近似相等,在给定一定容差(ε)的情况下足够接近。你可以争辩说>和<也受到这种近似过程的变幻莫测的影响。然而,通常人们愿意接受两种价值观具有<或>关系。
事实上,这可能是一个相当复杂的问题。这在很大程度上取决于你在做什么,以及你的应用程序对这些数值近似问题的容忍度。我知道有一个案例,AI算法受到从使用FPU指令到使用MMX/SSE/AVX的变化的影响。。。类型指令(PC FPU通常以80位进行内部计算,然后进行舍入,而AVX指令使用64位从干到尾)。在许多迭代过程中,基于舍入的差异导致采取不同的路径,从而导致不同的结果。这在很大程度上与这些类型的比较有关。你不能说这种方法(取决于FPU的行为)是不正确的,只能说它不能容忍对"较低分辨率"FP计算的更改。
std::max
不关心相等,它只关心两个数字不相等的情况。此外,ε与寻找由浮点误差引起的差的近似相等的数字有关。浮点误差应该导致std::max
选择一个而不是另一个,因为std::max
无法知道什么ε是合适的。
请记住,您的系统可能需要AreSame(0.1000001, 0.1) == true
,但std::max(0.1000001, 0.1)
应返回0.1000001
,以备不时之需。
- 如何在C++中从两个单独的for循环中添加两个数组
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- 如何返回一个类的两个对象相加的结果
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 两个字符串在 c++ 中不相等
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 使用 std::vector::swap 方法在C++中交换两个不同的向量是否安全?
- 最快和/或最安全的方法,在C 中加入两个宽字符串
- 两个不同流上的运算符<<(ostream&, obj)线程安全吗?
- 使用原子指令确保映射访问安全,是否可以使用两个不同的原子对指令进行重新排序
- 交换两个类实例的最安全方法
- 将两个字符安全转换为无符号短字符
- 将两个 std::vector<cv::P oint> 向量和安全公共点与第三个 std::vector<cv::P oint 进行比较>
- 取两个size_t对象的差异是否安全
- 在同一进程中使用的两个模块中具有同步对象的通用名称是否安全
- 从两个进程安全访问文件
- 正在使用std::max来比较两个替身是否安全
- boost条件不在具有两个生产者和一个消费者的线程安全队列上工作