首页 > 解决方案 > 人们如何在 C89 中检查 nan 和 inf

问题描述

isnan(), isinf()直到 C99 才出现在规范中,无论如何在 C89 中实现这样的功能?

我可以用它if (d * 0 != 0)来检查 d 是 NaN 还是 Inf,但我们总是使用-Werror=float-equal想要大喊大叫的选项来编译我们的项目:error: no == or != on float point value

那么人们如何在 C89 中检查 nan 和 inf 呢?

标签: cfloating-pointnanc99c89

解决方案


从C99开始

isinf(x)isnan(x)处理 和 的实浮点类型,x对于其他类型(如int. isinf(x)并且isnan(x)是宏。

isinf(x)isnan(x)使用相同的名称float, double, long double,因此就像一个重载的函数。

伊森夫

对于 C89,我们可以使用单独的函数来测试_MAX. 请注意,C89 没有定义long double.

“自己动手”isinf()可以使用以下内容。

#include <float.h>
int isinf_f(float x) { return x < -FLT_MAX || x > FLT_MAX; }
int isinf_d(double x) { return x < -DBL_MAX || x > DBL_MAX; }

请注意,C 不要求实现支持infinity。如果是这样,上述情况永远不会正确。

伊斯南

C89 的“自己动手”isnan()比较棘手。可以在下面作为函数或简单的宏来完成。功能依赖于现代的非数字行为,其中 Nan 永远不等于任何东西,甚至不等于它自己。C89没有指定,通常底层浮点系统遵循这一点。否则,您需要更特定于平台的方法。

/* Note `x` used twice here - so use with caution */
#define my_is_nan(x) ( (x) != (x) )

int isnan_f(float x) { x != x; }
int isnan_d(double x) { x != x; }

请注意,C 不要求实现支持Not-a-number。如果是这样,上述情况永远不会正确。

鉴于 C89 的狂野西部时代,我不会假设符合 IEEE 754。 InfinityNAN正是任何缺乏正式合规性的浮点实现的边缘。祝你好运。


C 允许使用 FP 更广泛的数学,这取决于FLT_EVAL_METHOD所以1.0f / 7.0f可能使用double. 这使事情有点复杂,但使用真正的函数确实会将x表达式强制转换为所需的类型。


推荐阅读