set :: find和std :: find都无法在集合中找到一些双元素

时间:2015-06-16 05:56:41

标签: c++ stl

我正在开发一个大的代码库,并希望使用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::findstd::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,同时我要求countstd::find分别统计和查找0.009。我只是想知道为什么我会看到这样的异常现象。

值得一提的是,find函数在查找整数元素时绝对没有问题。我想知道这是否是double问题。即使是这种情况,我也不确定为什么它能够找到一些元素而不是所有元素。

我不确定导致此错误的原因,但如果它有任何用处,我可以使用gcc 4.9.2在Mac OS X 10.10.3上工作。

1 个答案:

答案 0 :(得分:4)

是的,它是double&#34;问题&#34; - 当您将0.001连续添加到iter时,舍入错误可能会累积,使得结果值与您预期的值不匹配(例如您的硬编码0.008)。

由于set已排序,您可能需要使用,例如lower_bound找到附近的元素,然后使用一些容差来检查差异。例如,检查找到的值和期望值之间的绝对差值是否小于epsilon量。关于S.O.有数百个问题。关于如何实施比较......例如here

set中使用浮点数特定的另一个问题是,如果您预期insert被认为是重复的,或者另一方面insert可能会window.PKVideoThumbnail.createThumbnail ('file:///sdcard/ibhool/Video/ibhool.mp4', 'file:///sdcard/ibhool/Video/thumbtest.png', function(prevSucc) { return prevImageSuccess(prevSucc); }, fail); function prevImageSuccess(succ) { alert('success'); }', 拒绝插入两个您不希望重复的值,因为它们生成期间的舍入错误使它们保持相同。与您在数学上期望的完全准确的计算相比,两个非常相似的值的顺序也是可能的。