我有一个字符串,我将其转换为像这样的双字符:
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
//...
如何解决这个问题?
答案 0 :(得分:35)
您无需担心此警告。这在很多情况下都是无稽之谈,包括你的。
doubleValue
的文档并未说明它在溢出时返回的内容足够接近HUGE_VAL
或-HUGE_VAL
。它表示在溢出的情况下它会返回这些值。
换句话说,方法在溢出时返回的值会将==
与HUGE_VAL
或-HUGE_VAL
进行比较。
为什么警告首先存在?
考虑示例0.3 + 0.4 == 0.7
。此示例的计算结果为false。人们,包括你遇到的警告的作者,认为浮点==
是不准确的,并且意外的结果来自这种不准确。
他们都错了。
浮点添加是“不准确的”,因为某些不准确的意义:它返回您请求的操作的最近的可表示浮点数。在上面的示例中,转换(从十进制到浮点)和浮点加法是导致奇怪行为的原因。
另一方面,浮点相等的工作方式与其他离散类型完全相同。浮点相等是精确的:除了小的异常(NaN值和+0。和-0。的情况)之外,当且仅当所考虑的两个浮点数具有相同的表示时,等式才计算为真。 / p>
您不需要epsilon来测试两个浮点值是否相等。而且,正如Dewar says in substance一样,示例0.3 + 0.4 == 0.7
中的警告应位于+
上,而不是==
上,以使警告有意义。
最后,与epsilon相比,意味着不相等的值看起来相等,这不适合所有算法。
答案 1 :(得分:10)
在这种情况下,请尝试使用>=
和<=
。
答案 2 :(得分:5)
如果您确定自己的比较,并希望告诉它铿锵声,请用以下代码包围您的代码:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfloat-equal"
/* My code triggering the warnings */
#pragma clang diagnostic pop
答案 3 :(得分:0)
浮点数不应与==或!=进行比较,因为浮点类型不准确,这可能会在使用这些运算符时导致意外错误。 您应该测试浮子是否位于彼此的距离内(大部分时间称为“Epsilon”)。
看起来像这样:
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
}
答案 4 :(得分:0)
对于这个非常简单的用例来说,可能不是必需的,但是这里有一个示例,说明了在尝试检查数字是否等于-1时如何解决潜在的差异:
#include <float.h>
#include <math.h>
int main(void) {
float sales = -1;
// basically if sales == -1
if (fabs(1 + sales) < FLT_EPSILON) {
return 0;
}
}