gcc 我可以得到的行为-Wfloat-equal的所有比较,除了文字零?

8dtrkrch  于 2023-11-19  发布在  其他
关注(0)|答案(3)|浏览(149)

我想在我的构建选项中启用-Wfloat-equal(这是一个GCC标志,当通过==或!=运算符比较两个浮点指针数时会发出警告)。然而,在我使用的几个库的头文件中,以及我自己的代码的很大一部分中,我经常想使用if (x)if (x != 0)或其变体来分支浮点数或双精度浮点数的非零值。
因为在这些情况下,我绝对确定值是零-检查的值是显式零初始化的结果,calloc等-我看不到使用这种比较的缺点,而不是对我的near(x, 0)函数的更昂贵和更难读的调用。
有没有什么方法可以让-Wfloat-equal对所有其他类型的浮点数相等比较产生影响,但允许这些比较不加标记地通过?在库头文件中有足够多的示例,它们可能会严重污染我的警告输出。

6l7fqoea

6l7fqoea1#

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

k0pti3hp

k0pti3hp2#

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

#include <functional>

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

字符串
GCC不报告系统头的警告,这会导致相等性测试在系统头中发生。

hlswsv35

hlswsv353#

检查一个值是否等于零(正或负)的一种可能方法是使用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

相关问题