首页 > 解决方案 > 使用浮点常量进行设置和检查

问题描述

我知道这里有很多关于为什么浮动相等比较通常是一个坏主意的问题。我了解浮点表示问题、舍入问题、将浮点数静默提升为双精度数、在位级别依赖算术的危险等。但在我看来,这应该没问题,而且我发现没有任何问题似乎涵盖了这一点:

static const float MARKER = -500.0f; // some value well outside the range of valid values
std::vector<float> some_floats = {MARKER, 0.5f, 100.0f, 9.5f, MARKER, 0.f};
for (size_t i = 0; i< some_floats.size(); ++i) {
    if (some_floats[i] == MARKER) {             
       std::cout << i << std::endl;
    } else {
       // do some math
    }
}

输出如预期:

0
4

如果我-Wfloat-equal启用了(在 gcc 中,但在其他编译器中类似),它会将比较行标记为危险: comparing floating point with == or != is unsafe. 这里几乎所有的答案都说不要使用 == 或 !=, period。但我不明白为什么这里有问题。我只设置一次常量并在其他任何地方重新使用它,并且永远不会对该常量进行任何操作(例如算术)。我错过了什么吗?0.0f即使没有设置为常数,那又如何呢?

标签: c++floating-point

解决方案


只要您有信心MARKER并且它的副本不会被算术函数或其他东西改变,那么进行简单的比较就没有问题。
也许考虑不使用-Wfloat-equal全局但在本地禁用警告:

    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Wfloat-equal"
    /* your code */
    #pragma GCC diagnostic pop

或便携式等效物:https ://www.fluentcpp.com/2019/08/30/how-to-disable-a-warning-in-cpp/


推荐阅读