【问题标题】:Comparing a floating point to one or zero with Wfloat-equal option使用 Wfloat-equal 选项将浮点数与 1 或 0 进行比较
【发布时间】:2017-04-25 08:00:24
【问题描述】:

我对在代码中执行浮点相等比较的问题有点熟悉。

目前我在 (GCC, Clang) 上编译的代码库启用了以下选项:-Wfloat-equal

在代码库中有以下示例比较:

template <typename FloatType>
void foo(FloatType v) {
  if (v == FloatType(1)) {
   ...
  }
  else if (v == FloatType(0)) {
   ....
  }
}

foo函数调用如下:

double d = 123.98;
float f = 123.98f;

foo(d);
foo(f);

考虑到 1 和 0 的特殊情况,它们每个都有精确的浮点表示 (double, float) 并且代码显然是在完全相等之后,而不是在某个次要的附近区别——

有没有办法重写代码,使其不会引发相关的 Wfloat-equal 诊断,并且还可以移植并支持浮点和双精度类型?

【问题讨论】:

  • 您可以使用 GCC 的 #pragma GCC diagnostic push/pop/ignored 来禁用这些行的诊断。
  • 你可以随时使用memcmp
  • 那你为什么要把-Wfloat-equal传递给编译器呢?
  • 如果你使用memcmp,记住0可以用两种不同的位模式来表示。
  • @MarcGlisse 这是一个在构建过程中使用的选项——我无法控制它。

标签: c++ gcc floating-point compare clang


【解决方案1】:

如何使用std::equal_to。就 GCC 而言,它会在处理包括 float-equal 在内的系统头文件时禁用大量检查

template <typename FloatType>
void foo(FloatType v) {
  if (std::equal_to<FloatType>()(v,FloatType(1))) {
   ...
  }
  else if (std::equal_to<FloatType>()(v,FloatType(0))) {
   ....
  }
}

【讨论】:

  • 我认为这更像是一个错误(用户直接触发的库代码不会发出警告),而不是消除此类警告的预期方式。更容易理解的方法是编写 float_equal_no_warning 函数或类似函数。
猜你喜欢
  • 1970-01-01
  • 2013-11-19
  • 1970-01-01
  • 2021-05-28
  • 2017-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多