c++ - 使用浮点常量进行设置和检查
问题描述
我知道这里有很多关于为什么浮动相等比较通常是一个坏主意的问题。我了解浮点表示问题、舍入问题、将浮点数静默提升为双精度数、在位级别依赖算术的危险等。但在我看来,这应该没问题,而且我发现没有任何问题似乎涵盖了这一点:
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
即使没有设置为常数,那又如何呢?
解决方案
只要您有信心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/
推荐阅读
- python - 如何将 python 本地日期时间对象转换为 utc
- amazon-web-services - AWS Lambda:设备上没有剩余空间
- vue.js - Vue 可拖动克隆并拖动事件
- yaml - 由于列表键,Yq 解析 yaml 失败
- mongodb - 如何使重复的 Mongo 数据库与主数据库保持同步?
- clang-tidy - clang-tidy 中的“AnalyzeTemporaryDtors”选项是什么意思?
- opencv - 将 Gstreamer 启动转换为相机 OV9281 的 OpenCV 管道
- c# - 我的 android 头停止触发断点
- azure - 尝试从 Azure DevOps 管道运行 Power Shell 脚本以连接到 Azure Windows 2016 vm
- javascript - 多次使用 mongo 连接返回无法使用已结束的会话