对于除文字零之外的所有比较,我可以获得 -Wfloat-equal 的行为吗?

发布于 2024-10-19 05:04:32 字数 400 浏览 1 评论 0原文

我想在我的构建选项中启用 -Wfloat-equal (这是一个 GCC 标志,当通过 == 或 != 运算符比较两个浮点指针数字时会发出警告)。但是,在我使用的库的几个头文件以及我自己的代码的很大一部分中,我经常希望使用 if (x) 或 < code>if (x != 0) 或其变体。

因为在这些情况下,我绝对确定该值恰好为零 - 检查的值是显式零初始化、calloc 等的结果 - 我看不出使用此比较的缺点,而是与对我的 near(x, 0) 函数的调用要昂贵得多且可读性较差。

对于所有其他类型的浮点相等比较,是否有某种方法可以获得 -Wfloat-equal 的效果,但允许这些不带标记地通过?库头文件中有足够多的实例,它们可能会严重污染我的警告输出。

I'd like to enable -Wfloat-equal in my build options (which is a GCC flag that issues a warning when two floating pointer numbers are compared via the == or != operators). However, in several header files of libraries I use, and a good portion of my own code, I often want to branch for non-zero values of a float or double, using if (x) or if (x != 0) or variations of that.

Since in these cases I am absolutely sure the value is exactly zero - the values checked are the result of an explicit zero-initialization, calloc, etc. - I cannot see a downside to using this comparison, rather than the considerably more expensive and less readable call to my near(x, 0) function.

Is there some way to get the effect of -Wfloat-equal for all other kinds of floating point equality comparisons, but allow these to pass unflagged? There are enough instances of them in library header files that they can significantly pollute my warning output.

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

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

发布评论

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

评论(3

汹涌人海 2024-10-26 05:04:32

从你提出的问题来看,这个警告似乎是完全恰当的。如果您要与精确的零进行比较来测试数据是否仍然具有来自 calloc 的初始零值(从纯 C 的角度来看,这实际上是不正确的,但适用于任何符合 IEEE 754 的实现),您可能会因四舍五入为零的非零值而出现误报。换句话说,听起来您的代码不正确。

From the question you ask, it seems like the warning is entirely appropriate. If you're comparing against exact zero to test if data still has its initial zero value from calloc (which is actually incorrect from a standpoint of pure C, but works on any IEEE 754 conformant implementation), you could get false positives from non-zero values having been rounded to zero. In other words it sounds like your code is incorrect.

绾颜 2024-10-26 05:04:32

这非常可怕,但这避免了警告:

#include <functional>

template <class T>
inline bool is_zero(T v)
{
    return std::equal_to<T>()(v, 0);
}

GCC 不会报告系统标头的警告,这会导致相等测试发生在系统标头内。

It's pretty horrible, but this avoids the warning:

#include <functional>

template <class T>
inline bool is_zero(T v)
{
    return std::equal_to<T>()(v, 0);
}

GCC doesn't report warnings for system headers, and that causes the equality test to happen inside a system header.

神爱温柔 2024-10-26 05:04:32

检查值是否等于零(正数或负数)的一种可能方法是使用 std::fpclassify 函数(该函数可用于 C++ 以及 C)。

例如:

#include <iostream>
#include <cmath>
#include <cstdlib>

bool is_zero (float x)
{
    return std::fpclassify (x) == FP_ZERO;
}

int main (int, char **)
{
    float a {-0.f};
    float b {+1.f};

    std::cout << is_zero (a) << std::endl;
    std::cout << is_zero (b) << std::endl;

    return EXIT_SUCCESS;
}

构建:

g++ main.cpp -o main -std=c++17 -Wall -Wextra -Wfloat-equal -Wfloat-conversion -Wdouble-promotion

运行:

1
0

One possible way to check if a value is equal to zero (positive or negative) is using std::fpclassify function (which is available for C++ as well for C).

For example:

#include <iostream>
#include <cmath>
#include <cstdlib>

bool is_zero (float x)
{
    return std::fpclassify (x) == FP_ZERO;
}

int main (int, char **)
{
    float a {-0.f};
    float b {+1.f};

    std::cout << is_zero (a) << std::endl;
    std::cout << is_zero (b) << std::endl;

    return EXIT_SUCCESS;
}

Build:

g++ main.cpp -o main -std=c++17 -Wall -Wextra -Wfloat-equal -Wfloat-conversion -Wdouble-promotion

Run:

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