测试浮点数是否等于 0.0 是否安全?

发布于 2024-12-22 05:28:08 字数 227 浏览 2 评论 0原文

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

考虑以下代码:

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

I know it's dangerous to test floats for equality due to precision errors but is it safe to test for zero? I can think of some cases, for example in optimizing special cases in algorithms, where you would want to do this. The question is regarding floats but I would assume the answer also applies to doubles as well.

Consider the following code:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尤怨 2024-12-29 05:28:08

如果该值显式设置为 0.0f,则它会返回 true,从某种意义上说它是安全的。

从某种意义上说,这是不安全的,您不应期望计算结果恰好为 0.0f。

所以你实际上是使用 0.0f 作为某种特殊的魔法值,而不是与零进行真正的比较。

It is safe in the sense that if the value is set explicitly to 0.0f, it will return true there.

It is NOT safe in the sense that you should not expect that the value resultant from calculations will be exactly 0.0f.

So you're really using 0.0f as a special magic value of sorts, not as a real comparison against zero.

药祭#氼 2024-12-29 05:28:08

不,这不安全,因为 calculateFactor() 中的计算可能不会得到 0.0,即使按算术计算应该如此。一个简单的例子:使用 double 完成时 (0.4-0.1)-0.3 结果为 5.551115123125783e-17

No, it's not safe, because the calculation in calculateFactor() will probably not result in 0.0 even through it arithmetically should. A trivial example: (0.4-0.1)-0.3 when done using double results in 5.551115123125783e-17

吐个泡泡 2024-12-29 05:28:08

它当然是安全的,但您必须考虑它对您的算法意味着什么。如果您的算法使用 factor 作为除数(并且本身不检查是否被零除),那么检查 factor != 0.0f 在调用 applyComplexAlgorithm(factor) 之前。

现在,在使用 factor 之前是否应该检查小于某个 epsilon 的值,完全取决于您的代码的含义,并且不能单独根据您提供的代码来确定。

如果(正如您在另一条评论中提到的)您想使用特殊值 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);

It's certainly safe, but you do have to consider what it means for your algorithms. If your algorithm uses factor as a divisor (and doesn't check for divide-by-zero itself), then yes, it's perfectly reasonable to check for factor != 0.0f before calling applyComplexAlgorithm(factor).

Now, whether or not you should be checking for a value less than some epsilon before using factor, is totally up to what your code means and cannot be determined in isolation with the code you've provided.

If (as you alluded to in another comment) you want to use the special value 0.0f as a sentinel value that means something specific (such as the inability to calculate a factor), then yes, it's absolutely safe to compare using ==. For example, the following code's use of 0.0f is deterministic and is never subject to any kind of roundoff error:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文