微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在现代 C++ 中比较 double/float 是否相等的现代实践

如何解决在现代 C++ 中比较 double/float 是否相等的现代实践

if (std::abs(double1 - double2) < std::numeric_limits<double>::epsilon())
  std::cout<<"Equal";
else
  std::cout<<"Not equal";

这段代码与现代 C++11/14/17/21 是否仍然是我们应该比较 float 和 doubles 的方式,或者现在只需编写就可以了

if (double1 == double2)

编译器会为我们处理 epsilon 问题吗?

顺便说一句:在检查 epsilon 时写

解决方法

这段代码是否与现代 C++11/14/17/21 仍然是我们应该比较浮点和双精度的方式,或者现在只需编写 if (double1 == double2) 就可以了,编译器会为我们处理 epsilon 问题?

这两种方法在现代 C++ 中的功能与在早期 C++ 中的功能相同

这两种方法都有缺陷。

  • 使用 == 假定您的代码已经考虑了任何浮点舍入错误,而代码做到这一点非常罕见/困难。

  • 与 epsilon 比较假设合理数量的舍入误差将小于常数 epsilon,这很可能是错误的假设!

    • 如果您的数字具有大于 2.0 的量级,那么您的 epsilon 技巧将与直接比较没有区别,并且具有相同的缺陷。无论您使用 < 还是 <=
    • 如果您的数字符号相同且幅度小于 epsilon,您的 epsilon 技巧会说它们始终相等,即使一个比另一个大数百倍。它们也都等于零。

一种明智的方法可能是避免编写依赖于浮点数是否相等的代码。而是通过某种因素测试它们是否相对接近。

下面的代码将测试两个数字是否在彼此的 0.01% 以内。不管他们的规模如何。

const auto relative_difference_factor = 0.0001.    // 0.01%
const auto greater_magnitude = std::max(std::abs(double1),std::abs(double2));

if ( std::abs(double1-double2) < relative_difference_factor * greater_magnitude )
  std::cout<<"Relatively close";
else
  std::cout<<"Not relatively close";

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。