测试浮点数是否相等是否安全?

时间:2011-12-20 22:52:10

标签: comparison floating-point double precision equality

我知道由于精度错误而测试浮点数是否有危险但是测试零是否安全?我可以想到一些情况,例如在优化算法中的特殊情况时,您可能希望这样做。问题是关于花车,但我认为答案也适用于双打。

请考虑以下代码:

float factor = calculateFactor();
if(factor != 0.0f)
    applyComplexAlgorithm(factor);

3 个答案:

答案 0 :(得分:8)

在某种意义上说,如果将值明确设置为0.0f,那么它将是安全的。

从某种意义上说,你不应该期望计算得到的值恰好是0.0f,这是不安全的。

所以你真的使用0.0f作为排序的特殊魔法值,而不是与零的真实比较。

答案 1 :(得分:5)

不,这不安全,因为calculateFactor()中的计算可能不会导致0.0,即使是算术上也应如此。一个简单的例子:(0.4-0.1)-0.3使用double完成后导致5.551115123125783e-17

答案 2 :(得分:3)

肯定是安全,但您必须考虑它对您的算法意味着什么。如果你的算法使用factor作为除数(并且不检查除零本身),那么是的,在调用factor != 0.0f之前检查applyComplexAlgorithm(factor)是完全合理的。< / p>

现在,在使用factor之前,您是否应该检查小于某个epsilon的值,完全取决于您的代码的含义,并且无法与您提供的代码隔离。< / p>

如果(正如你在其他评论中提到的那样)你想使用特殊值0.0f作为哨兵值,这意味着特定的东西(例如无法计算因子),那么是的,它是绝对安全的使用==进行比较。例如,以下代码对0.0f的使用是确定性的,并且不会受到任何类型的舍入错误:

float calculateFactor()
{
    int phase = moon_phase();
    if (phase == FULL) {  // whatever special case requires returning 0.0f
        return 0.0f;
    } else {
        return 1.0 + (phase * phase); // something that is never 0.0f
    }
}

float factor = calculateFactor();
if(factor != 0.0f)
    applyComplexAlgorithm(factor);