1.#QNAN、1.#IND和1.#INF等“無效”浮點數說明及其判斷

PengPengBlog發表於2017-05-15
在GIS檢視上發現部分小區不能正常呈現,通過跟蹤異常小區發現其所屬基站的經緯度座標都是-1.#QNAN00000000000無效值,導致小區繪製失敗,這些小區均屬新入網的3G基站,資源資料還沒有維護起來,資料庫中對應欄位為空,經過TUXEDO介面後資料反映為QNAN無效值。在基礎資料完善之前,可在SQL取資料時將空值轉化為0,或在接收資料時對此類資料作進一步的過濾。
  此處的1.#QNAN是一個列印呈現,QNAN是指Quiet Not aNumber,類似的浮點錯誤還有SNaN(Signaling Not aNumber),通常如0.0/0.0、給負數開平方根等溢位或無效運算就會產生一個NAN結果的表示值,NaN及兩種浮點錯誤的說明如下:
The value NaN (Not a Number)is used to represent a value that does not represent a real number.NaN’s are represented by a bit pattern with an exponent of all 1sand a non-zero fraction. There are two categories of NaN: QNaN(Quiet NaN) and SNaN (Signalling NaN).
QNaN is a NaN withthe most significant fraction bit set. QNaN’s propagate freelythrough most arithmetic operations. These values pop out of anoperation when the result is not mathematically defined.
An SNaN is a NaN withthe most significant fraction bit clear. It is used to signal anexception when used in operations. SNaN’s can be handy to assign touninitialized variables to trap premature usage.
Semantically, QNaN’s denote indeterminate operations, while SNaN’sdenote invalid operations. If a return value is a QNaN, it meansthat it is impossible to determine the result of the operation, aSNaN means that the operation is invalid.
  這樣的特殊浮點數還有INF和IND:INF就是Infinity,表示一個無窮大的數,包括正無窮和負無窮;IND則表示無限小,但不確定。如1.0/0.0會產生一個INF無窮大,-1.0/0.0會產生一個負無窮大。
 
  回到最初的錯誤上,這種無效資料之所以通過了經緯度有效值判斷,是因為常規的浮點範圍對這類浮點數無效。我們知道常規的浮點數不能直接判0等於,而如果這個浮點數為NaN,那if(f==f) 會得到false結果。但是利用這個結果來判斷一個浮點數是否為NaN並不總是安全的,例如用這個巨集定義#defineisnan(x) ((x) != (x)),在某些編譯環境下可能就會脫離了你的預期。那如何判斷特殊的浮點數呢?各種語言應該都能找到對應的輔助函式或者類方法,在C語言中,可以用float.h中的int_isnan(double x)、int _finite(double x)、int _fpclass(doublex)函式來判斷,返回結果代表意義分別為:_FPCLASS_SNAN (Signaling NaN)、_FPCLASS_QNAN(Quiet NaN)、_FPCLASS_NINF (Negative Infinity, –INF)、_FPCLASS_PINF(Positive Infinity,+INF);在C++中,可以用STL中的limits類:numeric_limits::quiet_NaN()、numeric_limits::signaling_NaN()、numeric_limits::infinity()等方法。

相關文章