如果我为浮点数定义了自定义比较函数,std::sort 会正常工作吗?
Will std::sort work correctly if I defined a custom compare function for floating number?
对于浮点精度的问题,我为浮点数定义了自定义比较函数:
bool cmp(double a, double b)
{
if(abs(a - b) <= eps) return false;
return a < b;
}
然后我对一些浮点数数组调用排序。我听说一些不好的比较函数会导致排序分段错误。我只是想知道cmp
可以正常工作吗?一方面,cmp
满足关联规则。但另一方面,cmp(x - eps, x) == false
&&cmp(x, x + eps) == false
并不意味着cmp(x - eps, x + eps) == false
。
我没有直接对浮点数使用排序,因为我想排序的是pair<double, double>
.例如:
(1,2), (2,1), (2.000000001, 0)
我想将 2 和 2.000000001 视为相同,并期望结果为:
(1,2), (2.000000001, 0), (2,1)
>std::sort
需要一个定义严格弱排序的比较器。这意味着,除其他事项外,必须满足以下条件:
- 我们定义两个项目,
a
和b
,如果!cmp(a, b) && !cmp(b, a)
,则等价(a === b
- 等价是传递的:
a === b
&&b === c
=>a === c
正如您在问题中已经说过的,您的函数cmp()
不满足这些条件,因此您无法在 std::sort()
中使用您的函数。不仅算法的结果是不可预测的,这很糟糕,除非你真的在寻找这种不可预测性(参见)。 randomize
):如果有几个彼此非常接近的值,使得它们中的任何一个true
与某些值进行比较,但与其他一些值false
,则算法可能会进入无限循环。
所以答案是否定的,你不能在std::sort()
中使用你的函数cmp()
,除非你想冒着程序冻结的风险。
你为什么要费心做一个近似的小于比较?这是没有道理的。
只需严格按实际值对数组进行排序即可。
然后使用近似比较函数来确定您希望认为哪些元素相等。
(英语中的等价物是臭名昭著的"几乎更好"。想一想。
可以为浮点数定义一个比较函数,对相似的值进行分组。您可以通过四舍五入来实现:
bool cmp(double a, double b)
{
const double eps = 0.0001;
int a_exp;
double a_mant = frexp(a, &a_exp); // Between 0.5 and 1.0
a_mant -= modf(a_mant, eps); // Round a_mant to 0.00001
a = ldexp(a_mant, a_exp); // Round a to 0.00001 * 10^a_exp
// and the same for b
int b_exp;
double b_mant = frexp(b, &b_exp);
b_mant -= modf(b_mant, eps);
b = ldexp(b_mant, b_exp);
// Compare rounded results.
return a < b;
}
现在cmp(a,b)==true
暗示a<b
,a==b
和a>b
都暗示cmp(a,b)==false
。
- QSqlquery prepare()和bindvalue()不工作
- 为什么 std::unique 不调用 std::sort?
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- 对字符串进行排序时,在c++中处理sort()
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 为什么STD ::计数将常数传递给Lambda,而不是在弦上工作时而不是字符
- C STD :: getline / std :: Sort无法正常工作
- std::sort与不严格的弱排序比较器可以作为拓扑排序工作
- 如果我为浮点数定义了自定义比较函数,std::sort 会正常工作吗?
- 为什么C++sort()函数不以sort(vectorname)形式工作,而以sort形式工作(vectorname.b
- C++程序已停止工作-求解常微分方程
- std::sort() c++不工作,但它很简单,为什么:(1D数组