float f = (float)'a';
if(f < 0){
}
else if(f == 0){
}
else if(f > 0){
}
else{
printf("NaN\n");
}
f
如果它是NaN
將不會大於/等於/小於0
。如何在c中生成NaN浮點數?
但如何生產這樣的f
在第一位?
我嘗試過各種方法來產生NaN
,但沒有工作..
float f = (float)'a';
if(f < 0){
}
else if(f == 0){
}
else if(f > 0){
}
else{
printf("NaN\n");
}
f
如果它是NaN
將不會大於/等於/小於0
。如何在c中生成NaN浮點數?
但如何生產這樣的f
在第一位?
我嘗試過各種方法來產生NaN
,但沒有工作..
使用浮點數,0.0/0.0
是不是一個錯誤「被零除」;它導致NaN
。
這個C程序打印-nan
:
#include <stdio.h>
int main()
{
float x = 0.0/0.0;
printf("%f\n", x);
return 0;
}
在條款的外觀NaN
像電腦,兩個「無效」的數字保留爲「信號」和「安靜」南(類似於兩個無效號碼保留正負無窮大)。 Wikipedia entry有關於NaN如何表示爲IEE浮點數的更多詳細信息。
試過了,'NaN'沒有打印,所以不起作用。 –
@Je Rog:我的不好,我已經解決了我的問題。 –
@威廉,它的工作原理!但是'NaN'代表的是怎樣的?這意味着用於單精度和雙精度值的IEEE標準格式定義了一些無效值,可以用作'NaN',對吧? –
爲了產生楠,有一些方法:
1)手動生成(讀ieee754
正確設置的比特)
2)使用宏。 GCC公開了一個宏NAN
。它在math.h中定義
,檢查是否有楠的一般方法是檢查if (f == f)
(這應該失敗NaN值)
對於南,在浮點表示的指數位都應該被設置爲1 (float由一個有符號位,一組指數位和一組尾數位組成)
從GNU GCC手冊math.h
定義的宏允許您明確地將變量設置爲無窮大或NaN。既然這是C99的一部分,你可以使用下面的宏和我希望的其他c99兼容編譯器。
- 宏:float INFINITY 表示正無窮大的表達式。它等於數學運算產生的值,如1.0/0.0。 -INFINITY代表負無窮。
您可以通過將其與此宏進行比較來測試浮點值是否無限。但是,這不是建議;你應該使用isfinite宏代替。請參閱浮點類。
該宏是在ISO C99標準中引入的。
- Macro:float NAN 一個表達式表示「不是數字」的值。這個宏是GNU擴展,僅在支持「非數字」值的機器上可用,也就是說,在所有支持IEEE浮點的機器上。
您可以使用'#ifdef NAN'來測試機器是否支持NaN。 (當然,你必須安排GNU擴展是可見的,比如定義_GNU_SOURCE,然後你必須包含math.h.)
進一步的信息,你可以在這裏看到: http://www.gnu.org/s/hello/manual/libc/Infinity-and-NaN.html
'NAN'宏不是GNU擴展(至少不會)。它已經在ISO C99標準中引入。因此,不是定義'_GNU_SOURCE',而是以某種形式的C99模式或更高版本(而不是C89)編譯就足夠了。 – vinc17
這適用於常量太(0/0會給VS編譯器錯誤):
const unsigned maxU = ~0;
const float qNan = *((float*)&maxU);
至少有4個可移植性問題:有符號整數類型爲'〜',可能太短(例如在某些嵌入式系統上)的int,NaN表示和破壞的別名規則。有關詳細信息,請參閱[我的答案](http://stackoverflow.com/a/43496916/3782797)。 – vinc17
下面的C程序會產生NaN的。第二個聲明將導致NaN。
#include <stdio.h>
#include <tchar.h>
#include "math.h"
int _tmain(int argc, _TCHAR* argv[])
{
double dSQRTValue = sqrt(-1.00);
double dResult = -dSQRTValue; // This statement will result in a NaN.
printf("\n %lf", dResult);
return 0;
}
以下將是程序的輸出。
1.#QNAN0
既可以使用NAN
宏,或者乾脆nan/nanf
之一功能NaN值分配給變量。
檢查你是否正在處理一個nan值,你可以使用isnan()
。 下面是一個例子:
#include <stdio.h>
#include <math.h>
int main(void) {
float a = NAN;//using the macro in math.h
float f = nanf("");//using the function version
double d = nan("");//same as above but for doubles!
printf("a = %f\nf = %f\nd = %f\n",a,f,d);
if(isnan(a))
puts("a is a not a number!(NAN)\n");
return 0;
}
運行上面的代碼段會給你這樣的輸出:自己
a = nan
f = nan
d = nan
a is a not a number!(NAN)
運行代碼:http://ideone.com/WWZBl8
瞭解更多信息:http://www.cplusplus.com/reference/cmath/NAN/
爲什麼這篇文章被低估?! – Breeze
這可能是因爲'nan'和'nanf'不是標準的C函數。 – skyking
@skyking'nan'和'nanf' **是自1999年以來的標準ISO C函數**。 – MarkWeston
楠當我們編程時包含像0.0/0.0所述的值,如@Dan Cecile或sqrt(-1)所述。
對於託管的C實現,可以執行#include <math.h>
並使用NAN
宏(如果已定義)。例如,對於GCC,它由內建實現:(__builtin_nanf (""))
。
對於獨立C實現(在其上<math.h>
頭可能不可用),或者當沒有定義NAN
宏(這可能發生即使NaN的可被支撐),可以產生爲NaN具有浮點運算如0.0 / 0.0
。但是,它可能有幾個問題。
首先,這樣的操作也會產生一個異常,在某些C實現上可能存在陷阱。我們可以確保它被計算在編譯時間:
static double my_nan = 0.0/0.0;
另一個問題是,微軟的Visual C++(至少某些版本)嘗試在編譯時(以評估0.0 / 0.0
即使這種表達是在任意的地方在代碼中)並且抱怨它的有效性。所以,這裏的解決方案是相反的一個:確保編譯器不會在編譯時評價它,這樣做:
static double zero = 0.0;
,然後使用zero / zero
。由於這些解決方案有衝突,因此可以使用specific macros上的預處理器指令(#if
...)來測試編譯器。
人們也可以選擇基於NaN編碼的解決方案,但也存在可移植性問題。首先,IEEE 754標準並沒有完全定義NaN的編碼,特別是區分安靜和信令NaN(和實際中硬件不同)的方式;信號NaNs會產生未定義的行爲。而且,IEEE 754標準沒有定義如何在存儲器中表示比特串,即可能需要檢測字節序。如果這些問題得到解決,則使用指針轉換的聯合或unsigned char
的數組可以很好地獲得浮點類型。不要在其地址上使用帶有指針的整數進行類型雙擊,因爲這會破壞C別名規則。
http://www.gnu.org/s/hello/manual/libc/Infinity-and-NaN.html –
你可以使用一點C++嗎? C++有std :: numeric_limits的東西,其中包括用於安靜和信令NaN的常量。另外,你確定你的系統支持NaN嗎?因爲當你說0.0/0.0不是NaN時我真的很驚訝,我開始懷疑你的圖書館沒有按照你的想法設置。 –