将浮点数与零比较 [英] Comparing floating point number to zero

查看:173
本文介绍了将浮点数与零比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++常见问题解答[29.17]为什么我的浮点数比较无效? 建议这种平等测试:

  #include< cmath> / * for std :: abs(double)* / 

inline bool isEqual(double x,double y)
{
const double epsilon = / *一些小数字1e-5 * /;
return std :: abs(x-y)<= epsilon * std :: abs(x);
//见Knuth第4.2.2节第217-218页
}




  1. 这是正确的,这意味着只有等于零的数字是 +0 -0

  2. 应该在测试零时使用此函数,或者像 | x | < εilon

更新 $ b

正如丹尼尔·达拉纳斯所指出的,函数应该更好地被调用 isNearlyEqual (这是我关心的情况)。



有人指出了此链接,我想更明显地分享。

解决方案

您的观察是正确的。



如果 x == 0.0 ,则 abs(x)* epsilon 为零,您正在测试 abs(y)<= 0.0



y == 0.0 那么你正在测试 abs(x)< = abs(x)* epsilon epsilon> = 1 (不是)或 x == 0.0



因此 is_equal(val,0.0) is_equal(0.0,val)将是无意义的,你可以只说 val == 0.0 。如果您只想接受确切 +0.0 -0.0



在这种情况下,常见问题建议的作用有限。 没有一刀切的浮点比较。您必须考虑变量的语义,可接受的值范围以及计算引入的误差幅度。即使常见问题提到一个警告,说这个功能通常不是一个问题当x和y的大小明显大于epsilon,但你的里程可能会变化。


The C++ FAQ lite "[29.17] Why doesn't my floating-point comparison work?" recommends this equality test:

#include <cmath>  /* for std::abs(double) */

inline bool isEqual(double x, double y)
{
  const double epsilon = /* some small number such as 1e-5 */;
  return std::abs(x - y) <= epsilon * std::abs(x);
  // see Knuth section 4.2.2 pages 217-218
}

  1. Is it correct, that this implies that the only numbers which are equal to zero are +0 and -0?
  2. Should one use this function also when testing for zero or rather a test like |x| < epsilon?

Update

As pointed out by Daniel Daranas the function should probably better be called isNearlyEqual(which is the case I care about).

Someone pointed out this link, which I want to share more prominently.

解决方案

You are correct with your observation.

If x == 0.0, then abs(x) * epsilon is zero and you're testing whether abs(y) <= 0.0.

If y == 0.0 then you're testing abs(x) <= abs(x) * epsilon which means either epsilon >= 1 (it isn't) or x == 0.0.

So either is_equal(val, 0.0) or is_equal(0.0, val) would be pointless, and you could just say val == 0.0. If you want to only accept exactly +0.0 and -0.0.

The FAQ's recommendation in this case is of limited utility. There is no "one size fits all" floating-point comparison. You have to think about the semantics of your variables, the acceptable range of values, and the magnitude of error introduced by your computations. Even the FAQ mentions a caveat, saying this function is not usually a problem "when the magnitudes of x and y are significantly larger than epsilon, but your mileage may vary".

这篇关于将浮点数与零比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆