“-Weverything”屈服“比较==浮点或!=不安全”(“-Weverything” yiel

2019-06-26 04:21发布

我有我转换到这样一个双重的字符串:

double d = [string doubleValue];

对于文件doubleValue告诉我们,向上溢出,此方法将返回HUGE_VAL-HUGE_VAL 。 这是我检查这个早些时候:

if (d == HUGE_VAL || d == -HUGE_VAL)
   //overflow

现在,由于加入了新的“-Weverything”警告标志,则编译器现在抱怨

Comparing floating point with == or != is unsafe

我怎样才能解决这个问题? 我应该如何做这些比较?


我也有关于比较两个“正常”的浮点数(即不是“HUGE_VAL”的)同样的问题。 例如,

double a, b;
//...
if (a != b) //this will now yield the same warning
  //...

如何来解决?

Answer 1:

您不必担心此警告。 这是在很多情况下,包括你的废话。

的文档doubleValue不说,它返回的东西足够接近HUGE_VAL-HUGE_VAL溢出。 它说,它在溢出的情况下,正好返回这些值。

换句话说,通过该方法在溢出的情况下,返回的值进行比较==HUGE_VAL-HUGE_VAL

为什么警告摆在首位存在吗?

考虑例如0.3 + 0.4 == 0.7 。 这个例子计算结果为false。 人,包括你见过该警告的作者,认为浮点==是不准确的,那意想不到的结果来自于这种不准确性。

他们都错了。

浮点加法是“不准确的”,对于一些不准确的感觉:它返回您所请求的操作最接近的可表示浮点数。 另外,在上述的例子中,转换(从十进制浮点)和浮点加法是奇怪的行为的原因。

浮点平等 ,而另一方面,工作几乎完全一样,不会对其它分立类型。 浮点平等是准确的:除了少数例外,平等的计算结果为真当且仅当所考虑的两个浮点数字具有相同的表示(NaN的价值和+ 0的情况下,和-0.2)。

你并不需要一个小量测试如果两个浮点值相等。 而且,随着杜瓦实质上说 ,在本例中警告0.3 + 0.4 == 0.7应该是+ ,而不是== ,你的提醒是有道理的。

最后,埃普西隆内比较,意味着是不相等的值会显得相等,这是不适合所有的算法。



Answer 2:

在这种情况下,尝试使用>=<=



Answer 3:

如果你确信你比较,你要告诉它铛,环绕你的代码:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfloat-equal"
/* My code triggering the warnings */
#pragma clang diagnostic pop


Answer 4:

花车不应与==比较或!=由于float类型,使用这些运算符时可能导致意外的错误的不准确。 如果浮动,而不是谎言(称为“小量”的大部分时间)彼此的距离之内,您应该测试。

它看起来是这样的:

const float EPSILON = 1.0f; // use a really small number instead of this

bool closeEnough( float f1, float f2)
{
    return fabs(f1-f2)<EPSILON; 
    // test if the floats are so close together that they can be considered equal
}


文章来源: “-Weverything” yielding “Comparing floating point with == or != is unsafe”