浮点数NaN和INF(#IND, #INF)

89 篇文章 5 订阅
79 篇文章 4 订阅


参考:

http://www.cplusplus.com/reference/cmath/isnan/

isnan, _isnan, _isnanf | Microsoft Learn

http://blog.163.com/chen_dawn/blog/static/112506320125494852135/

-1.#IND,1.#INF 的判断_c语言ind0000-CSDN博客

isNaN_百度百科

http://bbs.csdn.net/topics/110121822

isnan isinf_linux isnan finite-CSDN博客

Checking if a double (or float) is NaN in C++ - Stack Overflow

Owed by: 春夜喜雨 春夜喜雨-CSDN博客  转载请标明来源 

NaN&INF定义

在一些情况会出现无效的浮点数,例如除0,例如负数求平方根等,像这类情况,获取到的浮点数的值是无效的。

NaN 即 Not a Number         非数字

INF  即 Infinite            无穷大

通常无效浮点数的内存表示方法是:

根据IEEE 754标准:
阶码全1,尾数全0表示无穷大INF。例如1.0/0.0

阶码全1,尾数非全0的表示无效数NaN。例如:求负数的平方根,例如0.0/0.0。

(注意: int型时除0是非法的,产生运行异常。Remember,integer division by 0 causes a runtime exception.)

INF无穷大:在doulbe/float时的取值

float f = 0; (4字节 1位符号位,8位指数,23位小数,指数偏移127)

*(UINT*)&f = 0x7F800000L;//正无穷(二进制 [0111 1111] [1000 0000] [0000 0000] [0000 0000])

*(UINT*)&f = 0xFF800000L;//负无穷(二进制 [1111 1111] [1000 0000] [0000 0000] [0000 0000])

double var = 0; (8字节 1位符号位,11位指数,52位小数,指数偏移1023)

// 因为通常是little endian,所以通常修改其前后4个字节

UINT* pVar = ((UINT*)&var) + 1;

*(pVar) = 0x7FF00000L;//正无穷

*(pVar) = 0xFFF00000L;//负无穷

常用的浮点数INF&NaN判断方法:

1.     Windows中,使用_isnan判断NaN情况;使用!_isnan && !_finite判断INF情况;使用!_finite判断NaN和INF两种情况

_isnan  //it returns a nonzero value if the argument x is a NaN;

_finite //It returns 0 if the argument is infinite or a NaN.

2.Linux中,使用insnan和isinf两个函数分别判别两种情况:

isNan

isInf

3.也可自己来写:

int isNaN(double x) {return x != x; }

#define _INF_DEFINE 1.0/0.0

int isInf(double n)

{

    static double pinf = 0.0;

    static double ninf = 0.0;

    if (pinf == 0.0) {

            pinf = _INF_DEFINE;

            ninf = -pinf;

    }

    return memcmp(&n, &pinf, sizeof(n)) == 0

            || memcmp(&n, &ninf, sizeof(n)) == 0;

}

依据:

1.   NaN是唯一与自身不等的浮点数类型,所以IsNan可以用 x != x来判断。Anything compared with NAN is false, so NAN == NAN is false.

2.   INF阶码全1,尾数全0

还有一种借用isNan定义INF的方法

int isInf(double x) {return !isNaN(x) && isnan(x-x);}

依据:

1.   Inf – Inf得到的为NaN

附一段测试代码

#include "stdio.h"

void ViewHex(double x)
{
	unsigned int* pUInt = ((unsigned int*)(&x));
	printf("0x%08X  ", *pUInt);
	pUInt++;
	printf("0x%08X\n", *pUInt);
}
int main()
{
	double a = 1.0/0.0;
	double b = 0.0/0.0;
	double c = a-a;
	printf("%f\n%f\n%f\n", a, b, c);
	printf("%f\n%f\n%f\n", -a, -b, -c);
	ViewHex(a);
	ViewHex(b);
	ViewHex(c);
	ViewHex(-a);
	ViewHex(-b);
	ViewHex(-c);
	getchar();
        return 0;
}

// 测试输出(运行环境: window 编译程序:mingw/gcc)

inf

nan

nan

-inf

nan

nan

0x00000000 0x7FF00000

0x00000000 0xFFF80000

0x00000000 0xFFF80000

0x00000000 0xFFF00000

0x00000000 0x7FF80000

0x00000000 0x7FF80000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春夜喜雨

稀罕你的喜欢!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值