出于鲁棒性原因,我想检查浮点数是IEEE-754 + -Inf还是IEEE-754 Nan。我的代码如下,我想知道它是否正确:
#define PLUS_INFINITE (1.0f/0.0f)
#define MINUS_INFINITE (-1.0f/0.0f)
#define NAN (0.0f/0.0f)
float Local_Var;
/*F is a float numnber.*/
if((unsigned long)(F) == 0x7f800000ul)
{
Local_Var = PLUS_INFINITE;
}
elseif((unsigned long)(F) == 0xff800000ul)
{
Local_Var = MINUS_INFINITE;
}
/*fraction = anything except all 0 bits (since all 0 bits represents infinity).*/
elseif((((unsigned long)(F) & 0x007ffffful) != 0ul )
&&((unsigned long)(F) == 0x7f800000ul))
||
(((unsigned long)(F) & 0x807ffffful) != 0ul )
&&
((unsigned long)(F) == 0xff800000ul))
{
Local_Var = NAN;
}
else{}
答案 0 :(得分:10)
C99具有用于浮点数分类的宏:
fpclassify(x)
返回以下内容之一:
FP_NAN
:x
不是数字; FP_INFINITE
:x
为正或负无限; FP_ZERO
:x
为零; FP_SUBNORMAL
:x
太小,无法以标准格式或FP_NORMAL
:正常的浮点数,即以上都不是。还有一些快捷方式可以检查其中一个类,如果x
是什么,则会返回非零值:
isfinite(x)
isnormal(x)
isnan(x)
isinf(x)
参数x
可以是任何浮点表达式;宏检测参数的类型并适用于float
和double
。
编辑:由于您不想使用(或不能使用)<math.h>
,您可以使用nan和inf的其他属性对您的数字进行分类:
nan
将false与所有数字进行比较,包括对自身的数字; inf
大于FLT_MAX
; -inf
小于-FLT_MAX
。所以:
#include <stdlib.h>
#include <stdio.h>
#include <float.h>
int main()
{
float f[] = {
0.0, 1.0, FLT_MAX, 0.0 / 0.0, 1.0/0.0, -1.0/0.0
};
int i;
for (i = 0; i < 6; i++) {
float x = f[i];
int is_nan = (x != x);
int is_inf = (x < -FLT_MAX || x > FLT_MAX);
printf("%20g%4d%4d\n", x, is_nan, is_inf);
}
return 0;
}
在此解决方案中,如果要使用double
,则必须调整限制。
答案 1 :(得分:2)
将漂浮物浇铸成长片就好了。它应该是一个联合或一个类型惩罚的指针。
以下是dietlibc(双打)的一个工作示例:
https://github.com/ensc/dietlibc/blob/master/lib/__isinf.c
https://github.com/ensc/dietlibc/blob/master/lib/__isnan.c
Musl有一个较短的fpclassify,以及浮动的适当常量:
http://git.musl-libc.org/cgit/musl/tree/src/math/__fpclassifyf.c
答案 2 :(得分:0)
最好使用@M Oehm answer
的fpclassify()
个功能
备选方案:
float F;
if (F <= FLT_MAX) {
if (F >= -FLT_MAX) {
puts("Finite");
} else {
puts("-Infinity");
}
} else {
if (F > 0) {
puts("+Infinity");
} else {
puts("NaN");
}
}
如果代码想要弄乱这些位并假设float
采用binary32格式:
assert(sizeof (float) == sizeof (uint32_t));
union {
float f;
uint32_t u32;
} x;
x.f = F;
掩码取决于float
和uint32_t
endian的相对端。它们通常都是一样的。
// Is F one of the 3 special: +inf, -inf, NaN?
if (x.u32 & 0x7F800000 == 0x7F800000) {
if (x.u32 & 0x007FFFFF) {
puts("NaN");
} else if (x.u32 & 0x80000000) {
puts("-Inf");
} else {
puts("+Inf");
}
}