我试图在包含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等)。这可能是问题吗?我可以将这个特定计算的值四舍五入吗?
答案 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。
通过添加舍入函数调用,并删除const我能够找到两位小数的平均值。
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;
}