浮点值可以加零吗?

时间:2011-10-28 16:22:30

标签: c++ c floating-point

  

可能重复:
  Most effective way for float and double comparison

我有两个值(浮动)我试图加在一起并平均。我遇到的问题是偶尔这些值会加起来为零,因此不需要对它们进行平均。

我所处的情况特别包含值“-1”和“1”,但当加在一起时,我得到的值是“-1.19209e-007”,显然不是0.有关此的任何信息吗?

4 个答案:

答案 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.而是测试是否低于某个阈值你想要用作零。