我遇到了一段在gcc
下会输出警告的代码:
float f;
// Calculate a value for f
if (!f == 0.0)
{
// Handle it being non-zero
}
很可能只是其他团队成员的笔误,仔细检查代码后,真正意思应该是:
if (f != 0.0)
// OR
if (!(f == 0.0))
我已经更正了代码,但我想知道!NaN
会评估为什么。我们在if
内部使用f
值,所以我们不希望NaN
通过检查。
我遇到了一段在gcc
下会输出警告的代码:
float f;
// Calculate a value for f
if (!f == 0.0)
{
// Handle it being non-zero
}
if (f != 0.0)
// OR
if (!(f == 0.0))
我已经更正了代码,但我想知道!NaN
会评估为什么。我们在if
内部使用f
值,所以我们不希望NaN
通过检查。
if
语句中出现NaN,可以使用以下函数进行检查:bool isnan( float arg );
。从该函数的参考文献中可以得知:“NaN值永远不等于它们自己或其他NaN值。根据IEEE-754标准,复制NaN不需要保留其位表示(符号和有效数字),但大多数实现会这样做。” 另一种测试浮点值是否为NaN的方法是将其与自身进行比较。bool is_nan(double x) { return x != x; }
!
的操作数在上下文中转换为bool(第7条款);如果转换后的操作数为false
,则其值为true
,否则其值为false
。结果的类型为bool。!NaN
中被上下文转换为true
,所以!NaN
为false
,因此不是NaN。请查看https://en.cppreference.com/w/cpp/language/implicit_conversion
整型、浮点型、未作用域枚举类型、指针和成员指针类型的 prvalue 可以转换为 bool 类型的 prvalue。
值为零(对于整型、浮点型和未作用域枚举类型)、空指针和空成员指针值变为 false。所有其他值变为 true。
因此,!f == 0.0
等同于 !(f != 0.0) == 0.0
或者 (f == 0.0) == false
或者 f != 0.0
NaN != 0
抛出异常,那么 !NaN
也会抛出异常。 - Alan Birtles!=
用于无序比较时返回true。抱歉,评论已删除。 - Pete Becker只需简单地使用
if (!isnan(f)&& !f == 0.0)
{
cout<<"Filtered NaN values"<<endl;
}
f != 0.0
可能不足够。您可能需要在其中使用epsilon。 - user4581301f
在条件语句之前被初始化了吗?你怎么知道f
的值是NaN? 你收到了哪些警告? - Some programmer dudef
应该永远不会是NaN
(除非宇宙射线扭曲了一两个位!)- 这只是为了满足我的好奇心,而不是实际的生产 bug,因此使用了 [tag:language-lawyer] 标签。 - Ken Y-Nf
中得到什么信息的唯一给定信息是// 计算 f 的值
,这表明涉及到一些数学。NaN 是一个奇怪的生物,有许多形态。期待看到语言专家对!NaN
意味着什么做出的回应。 - user4581301