我有两个值(浮动)我试图加在一起并平均。我遇到的问题是偶尔这些值会加起来为零,因此不需要对它们进行平均。
我所处的情况特别包含值“-1”和“1”,但当加在一起时,我得到的值是“-1.19209e-007”,显然不是0.有关此的任何信息吗?
答案 0 :(得分:4)
我很抱歉,但这对我没有意义。 两个浮点值,如果它们完全相同但符号相反,则减去将始终为0.这就是浮点运算的工作原理。
float a = 0.2f;
float b = -0.2f;
float f = (a - b) / 2;
printf("%f %d\n", f, f != 0); // will print out 0.0000 0
如果编译器没有优化代码,也将始终为0。 如果a和b具有相同的值但符号相反,则不会考虑任何类型的舍入误差!也就是说,如果a的高位为0且b的高位为1且所有其他位相同,则结果不能为0。
但是,如果a和b略有不同,当然结果可能是非零的。
避免这种情况的一种可能解决方案是使用容差......
float f = (a + b) / 2;
if (abs(f) < 0.000001f)
f = 0;
我们使用简单的容差来判断我们的值是否接近于零。
显示这个的一个很好的示例代码是......
int main(int argc)
{
for (int i = -10000000; i <= 10000000 * argc; ++i)
{
if (i != 0)
{
float a = 3.14159265f / i;
float b = -a + (argc - 1);
float f = (a + b) / 2;
if (f != 0)
printf("%f %d\n", a, f);
}
}
printf("completed\n");
return 0;
}
我在这里使用“argc”作为强制编译器不优化代码的技巧。
答案 1 :(得分:2)
至少在右边,这听起来像典型的浮点不精确。
处理它的常用方法是将数字四舍五入到正确的有效位数。在这种情况下,您的平均值为-1.19209e-08
(即0.00000001192
)。要(比方说)六或七位有效数字, 为零。
答案 2 :(得分:1)
取所有数字的总和除以你的数量。在你进行打印,报告比较或者你正在做的任何事情之前,将你的答案完成一些合理的答案。
答案 3 :(得分:0)
再次,对此进行一些搜索,但这是基本的解释......
计算机通过基数2而不是基数10来近似浮点数。这意味着,例如,0.2(当转换为二进制时)实际上是0.001100110011 ...永远。由于计算机无法永久添加这些,因此必须接近它。
由于这些近似值,我们失去了计算的“精确度”。因此“单”和“双”精度浮点数。这就是为什么你从来没有测试浮点数实际为0.而是测试是否低于某个阈值你想要用作零。