浮點數NaN和INF(#IND, #INF)
參考:
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。
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.
_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
#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