在Float向量中找到模式

时间:2018-01-23 17:42:30

标签: c++ vector statistics

我试图在包含324个浮点值的向量中找到模式平均值。

我的代码如下:

float max = vec.back();
float prev = max;
float mode = 0.0;
int maxcount = 0;
int currcount = 0;

for (const auto n : vec) {
    if (n == prev) {
        ++currcount;
        if (currcount > maxcount) {
            maxcount = currcount;
            mode = n;
        }
    } else {
        currcount = 1;
    }
    prev = n;
}

std::cout << mode << std::endl

这会将模式打印为0.75,这是错误的。

以下是所有浮点值,它们来自txt文件,请原谅格式:

0.61 0.61 0.61 0.62 0.62 0.62 0.62 0.62 0.62 0.62 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.63 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.64 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.65 0.66 0.66 0.66 0.66 0.66 0.66 0.66 0.66 0.66 0.66 0.66 0.66 0.66 0.66 0.66 0.66 0.66 0.66 0.66 0.67 0.67 0.67 0.67 0.67 0.67 0.67 0.67 0.67 0.67 0.67 0.67 0.67 0.67 0.67 0.67 0.67 0.67 0.67 0.67 0.67 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.68 0.69 0.69 0.69 0.69 0.69 0.69 0.69 0.69 0.69 0.69 0.69 0.69 0.69 0.69 0.69 0.69 0.69 0.69 0。 69 0.69 0.69 0.7 0.7 0.7 0.7 0.7 0.7 0.7 0.7 0.7 0.7 0.7 0.7 0.7 0.7 0.7 0.7 0.7 0.7 0.7 0.7 0.71 0.71 0.71 0.71 0.71 0.71 0.71 0.71 0.71 0.71 0.71 0.71 0.71 0.71 0.72 0.72 0.72 0.72 0.72 0.72 0.72 0.72 0.72 0.72 0.72 0.72 0.72 0.72 0.72 0.72 0.72 0.72 0.72 0.72 0.73 0.73 0.73 0.73 0.73 0.73 0.73 0.73 0.73 0.73 0.73 0.73 0.73 0.74 0.74 0.74 0.74 0.75 0.75 0.75 0.75 0.75 0.75 0.75 0.75 0.75 0.76 0.76 0.76 0.76 0.76 0.76 0.76 0.76 0.76 0.76 0.77 0.77 0.77 0.77 0.77 0.77 0.78 0.78 0.78 0.78 0.78 0.78 0.78 0.78 0.78 0.78 0.79 0.79 0.79 0.79 0.79 0.79 0.79 0.79 0.79 0.79 0.79

Excel将模式显示为0.65。为什么我的代码不会产生相同的结果?我需要改变什么?

非常感谢。

编辑:我发现通过调试vec中的值更像是; 0.68000000000000005,0.69999999999999996,虽然有些仍然只有两个小数点(0.64,0.74等)。这可能是问题吗?我可以将这个特定计算的值四舍五入吗?

2 个答案:

答案 0 :(得分:0)

问题可能是使用花车进行比较。由于它们的存储方式,浮点数通常与它们初始化的值相差很小。

不要使用n == prev,而是考虑在一个小的epsilon中进行比较,该比较大于machine precision(对于您希望运行此代码的任何机器),但小于任何机器之间的最小真实差异你的两个数字(看起来像0.01)。所以你可以做到

if (((n - prev) < EPSILON) && ((prev - n) < EPSILON)) { ...`

表示float EPSILON = 0.000001,或者对您有意义的值。 另见this question on comparing floats。值得注意的是,如果您的数据集更改为更大或更小的数字,理想的epsilon会发生变化。

即使您的代码中存在其他问题,您也可以考虑放弃一般的比较浮点数。

答案 1 :(得分:0)

通过调试我发现我的值不只是两个小数位值,因此,平均值实际为0.7500000000004,但仍然打印为0.75。

通过添加舍入函数调用,并删除co​​nst我能够找到两位小数的平均值。

 for (auto n : vec)
    {
        n = roundf(n * 100) / 100;

        if (n == prev)
        {
            ++currcount;
            if (currcount > maxcount)
            {

                maxcount = currcount;
                mode = n;

            }
        } else
        {
            currcount = 1;
        }
        prev = n;

    }