檢查 NaN 數據值 (C/C++/Python 實現)


  NaN 是 Not a Number 的縮寫.它是一個數值類型值,通常在浮點計算中,表示未定義或無法表示的值.而且,不能直接使用相等運算符 (==) 檢查 NaN.由於在程序中,nan == nan (C/C++/Python) 或 nan is nan (Python) 總是返回 0 或 False.因此,除了采用庫函數外,往往可以利用這個性質檢查某個數值是否為 NaN.下面介紹如何采用庫函數檢查 NaN 值:

 

C/C++ 實現

在 C/C++ 中,采用 math.h 標准函數庫中的 isnan 宏或函數檢查 nan 值,具體示例代碼如下:

C 代碼 test-nan.c

/* isnan example */ #include <stdio.h>      /* printf */ #include <math.h>       /* isnan, sqrt */

int main() { printf ("isnan(0.0) : %d\n",isnan(0.0)); printf ("isnan(1.0/0.0) : %d\n",isnan(1.0/0.0)); printf ("isnan(-1.0/0.0) : %d\n",isnan(-1.0/0.0)); printf ("isnan(sqrt(-1.0)): %d\n",isnan(sqrt(-1.0))); return 0; }

編譯和運行結果,如下所示

$ gcc test-nan.c -lm $ ./a.out isnan(0.0)       : 0 isnan(1.0/0.0)   : 0 isnan(-1.0/0.0)  : 0 isnan(sqrt(-1.0)): 1

C++ 代碼 test-nan.cpp

/* isnan example */ #include <cmath>       /* isnan, sqrt */ #include <iostream> using namespace std; int main() { cout << "isnan(0.0) : " << isnan(0.0) << endl; cout << "isnan(1.0/0.0) : " << isnan(1.0/0.0) << endl; cout << "isnan(-1.0/0.0) : " << isnan(-1.0/0.0) << endl; cout << "isnan(sqrt(-1.0)): " << isnan(sqrt(-1.0)) << endl; return 0; }

編譯和運行結果,如下所示

$ g++ test-nan.cpp  $ ./a.out isnan(0.0)       : 0 isnan(1.0/0.0)   : 0 isnan(-1.0/0.0)  : 0 isnan(sqrt(-1.0)): 1

如果在編譯時增加 -std=c++11 ,采用C++ 2011標准編譯程序,可能會出現如下錯誤:

$ g++ test-nan.cpp -std=c++11 ... error: call of overloaded ‘isnan(double)’ is ambiguous ...

一個簡單的解決方法是在所有的 isnan 宏或函數前,增加域操作符( :: ),修改后的示例代碼如下:

/* isnan example */ #include <cmath>       /* isnan, sqrt */ #include <iostream>

using namespace std; int main() { cout << "isnan(0.0) : " << ::isnan(0.0) << endl; cout << "isnan(1.0/0.0) : " << ::isnan(1.0/0.0) << endl; cout << "isnan(-1.0/0.0) : " << ::isnan(-1.0/0.0) << endl; cout << "isnan(sqrt(-1.0)): " << ::isnan(sqrt(-1.0)) << endl; return 0; }

保存后,重新編譯運行即可.

 

Python 實現

Python 采用 numpy 數值數學庫函數 np.isnan 檢查 nan 值,示例代碼 test-nan.py 如下:

#!/usr/bin/env python # -*- coding: utf8 -*- # author: klchang
from __future__ import print_function import numpy as np print ("isnan(0.0) : ", np.isnan(0.0)) print ("isnan(1.0/0.0) : ", np.isnan(np.true_divide(1.0, 0.0))) print ("isnan(-1.0/0.0) : ", np.isnan(np.true_divide(-1.0, 0.0))) print ("isnan(sqrt(-1.0)): ", np.isnan(np.sqrt(-1.0)))

運行輸出結果,如下:

$ python test-nan.py isnan(0.0) : False ...: RuntimeWarning: divide by zero encountered in true_divide print ("isnan(1.0/0.0) : ", np.isnan(np.true_divide(1.0, 0.0))) isnan(1.0/0.0) : False ...: RuntimeWarning: divide by zero encountered in true_divide print ("isnan(-1.0/0.0) : ", np.isnan(np.true_divide(-1.0, 0.0))) isnan(-1.0/0.0) : False ...: RuntimeWarning: invalid value encountered in sqrt print ("isnan(sqrt(-1.0)): ", np.isnan(np.sqrt(-1.0))) isnan(sqrt(-1.0)):  True

 

參考資料

1. isnan macro/function - <cmath> reference. http://www.cplusplus.com/reference/cmath/isnan/

2. NaN - Wikipedia, the free encyclopedia. https://en.wikipedia.org/wiki/NaN

3. numpy isnan - NumPy Manual. https://docs.scipy.org/doc/numpy/reference/generated/numpy.isnan.html

4. Why is isnan ambigous and how to avoid it? - stackoverflow. https://stackoverflow.com/questions/33770374/why-is-isnan-ambiguous-and-how-to-avoid-it

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM