set::find 和 std::find 都无法在一个集合中找到一些双元素
Both set::find and std::find fail to find only some double elements in a set
我正在开发一个大代码库,并希望使用 STL 中的 set-s 来存储双元素。我刚刚进行了一些测试,发现了一些非常奇怪的东西。
这是我的源代码
#include <iostream>
#include <set>
#include <numeric>
#include <algorithm>
int main()
{
double iter = 0.001;
int count = 0;
std::set<double> S;
while(count < 10)
{
S.insert(iter);
std::cout << "Inserted element is " << iter << std::endl;
iter += 0.001;
count++;
}
for (std::set<double>::iterator i = S.begin(); i != S.end(); i++)
{
double element = *i;
std::cout << "The element in the set is " << element << std::endl;
}
std::cout << "The count of the element to be found is " << S.count(0.009) << std::endl;
if (S.find(0.008) != S.end())
std::cout << "set::find found it!" << std::endl;
else
std::cout << "set::find didn't find it!" << std::endl;
if (std::find(S.begin(), S.end(), 0.009) != S.end())
std::cout << "std::find found it!" << std::endl;
else
std::cout << "std::find didn't find it!" << std::endl;
return 0;
}
现在,奇怪的是,set::find
和std::find
都能够找到所有元素,直到0.008
,但在那之后找不到任何东西。
我为上述代码获得的输出如下所示:
Inserted element is 0.001
Inserted element is 0.002
Inserted element is 0.003
Inserted element is 0.004
Inserted element is 0.005
Inserted element is 0.006
Inserted element is 0.007
Inserted element is 0.008
Inserted element is 0.009
Inserted element is 0.01
The element in the set is 0.001
The element in the set is 0.002
The element in the set is 0.003
The element in the set is 0.004
The element in the set is 0.005
The element in the set is 0.006
The element in the set is 0.007
The element in the set is 0.008
The element in the set is 0.009
The element in the set is 0.01
The count of the element to be found is 0
set::find found it!
std::find didn't find it!
请注意,我要求set::find
查找0.008
,而我要求count
和std::find
分别计数和查找0.009
。我只是想知道为什么我会看到这样的异常。
还值得一提的是,这两个find
函数在查找整数元素时绝对没有问题。我想知道这是否是一个double
问题。即使是这样,我也不确定为什么它能够找到一些元素而不是全部。
我不确定是什么原因导致此错误,但如果它有任何用处,我会在带有 gcc 10.10.3 的 Mac OS X 4.9.2 上工作。
> 是的,这是一个double
"问题" - 当您连续将0.001
添加到iter
时,舍入误差可能会累积,以至于结果值与您预期的不匹配(例如,您的硬编码0.008
)。
由于set
已排序,因此您可能希望使用例如 lower_bound
查找附近的元素,然后使用一些差异容差进行检查。 例如,检查找到的值和期望值之间的绝对差值是否小于 epsilon 量。 S.O.上有数百个关于如何准确实施比较的问题......例如这里。
set
中使用浮点数的另一个具体问题是,当您期望它们时,您可能不会insert
被视为重复项,或者另一方面,insert
可能会拒绝插入两个您不希望是重复的值,因为它们生成过程中的舍入误差使它们相同。 在给定完全准确的计算的情况下,两个极其相似的值的顺序也可能与您在数学上期望的顺序相反。
- 处理多个异常集合的C++方法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- 如何将ampl中的集合表示为c++中的向量
- 检查值是否在集合p1和p2中,但不在p3中
- 带过滤器的现代迭代c++集合
- 如何将结构插入到集合中并打印集合的成员
- 集合上的输出迭代器:assign和increment迭代器
- 如何将函数集合传递给客户端类,以便将它们当作客户端类本身的成员使用
- OpenMP卸载说'fatal error: could not find accel/nvptx-none/mkoffload'
- 实现一个在集合上迭代的模板函数
- 尝试使用集合函数时出现分段错误
- 互斥指针的集合
- c++找不到具有相同哈希的无序集合元素
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- python集合的C++等价物是什么.计数器
- 为什么 std::find( s.begin(), s.end(), val ) 比集合 s 的 s.find(val) 慢 1000 倍<int>?
- find() 函数对集合有效吗?
- set::find()找不到集合中的键
- set::find 和 std::find 都无法在一个集合中找到一些双元素