2012-07-02 76 views
8

什麼是1.#INF爲什麼投射到floatdouble可以防止0的碰撞分裂?
此外,如何防止除以0的任何偉大的想法? (像任何宏或模板)?除以零預防

int nQuota = 0; 

int nZero = 3/nQuota; //crash 
cout << nZero << endl; 

float fZero = 2/nQuota; //crash 
cout << fZero << endl; 

如果我使用來代替:

int nZero = 3/(float)nQuota; 
cout << nZero << endl; 
//Output = -2147483648 

float fZero = 2/(float)nQuota; 
cout << fZero << endl; 
//Output = 1.#INF 
+2

哇有趣。期待一個答案。 –

+0

這可能是對你有意思:http://blog.regehr.org/archives/721 – cppanda

回答

12

1.#INF是正無窮大。當你將正浮點數除以零(如果你將浮點數零除以零,那麼結果將是「不是數字」)。

另一方面,如果用零除整數,程序將崩潰。

原因float fZero = 2/nQuota;崩潰是因爲/運算符的兩個操作數都是整數,所以除法是在整數上執行的。然後將結果存儲在浮點中並不重要; C++沒有目標輸入的概念。

爲什麼正無窮大轉換爲整數是最小的整數,我不知道。

+0

怎麼樣-2147483648? –

+1

-2147483648是1.#轉換爲一個整數。 –

+3

C規範似乎沒有指定將'NaN'或無限浮點值轉換爲整數的結果。 「如果FL浮動值是在無限或NaN或者如果FL浮動值的整數部分超過 整數類型的範圍,那麼‘‘無效’’浮點數異常上升,所得到的值是unspeci網絡編」 – mkb

1

您通常會檢查以確保您沒有被零除。下面的代碼是不是特別有用,除非nQuota具有合法的值,但它並防止崩潰

int nQuota = 0; 
int nZero = 0; 
float fZero = 0; 
if (nQuota) 
    nZero = 3/nQuota; 
cout << nZero << endl; 

if (nQuota) 
    fZero = 2/nQuota; 
cout << fZero << endl; 
+0

有點簡單,但它像一個魅力。 –

3

Wwhy使用(浮點)或(雙)防止被0除崩潰的?

它不一定。當涉及到浮點時,標準是非常有用的。現在大多數系統都使用IEEE浮點標準,並且表示除零的默認操作是返回±無窮大而不是崩潰。您可以通過啓用適當的浮點異常來使其崩潰。

注意:浮點異常模型和C++異常模型唯一共同之處是單詞「exception」。在我工作的每臺機器上,浮點異常不會拋出C++異常。

另外,如何防止除以0的任何偉大的想法?

  1. 答案很簡單:不要這樣做。
    這是其中的一個「醫生,當我這樣做時醫生會傷害!」種情況。所以不要這樣做!

  2. 確保除數不爲零。
    對用戶輸入的除數進行完整性檢查。始終過濾您的用戶輸入以保持完整。當數字應該爲百萬時,用戶輸入值爲零將導致除溢出之外的各種破壞。對中間值進行完整性檢查。

  3. 啓用浮點異常。
    使默認行爲允許錯誤(這些幾乎總是錯誤)通過未經檢查是恕我直言,這是標準委員會的一大錯誤。使用默認值,這些無限和非數字將最終將所有變成Inf或NaN。
    默認應該已經停止漂浮在他們的蹤跡點的誤差,同時可以選擇允許像1.0/0.0和0.0/0.0的事情發生。事實並非如此,所以你必須啓用這些陷阱。這樣做,你可以在短時間內找到問題的原因。

  4. 編寫自定義鴻溝,自定義乘,自定義平方根,自定義正弦,...功能。
    這不幸的是許多安全關鍵軟件系統必須採用的路線。這是一種皇家的痛苦。選項#1出來了,因爲這只是一廂情願的想法。由於系統不能被允許崩潰,所以選項#3已關閉。選項#2仍然是一個好主意,但它並不總是有效,因爲糟糕的數據總是有偷偷摸摸的方式。這是墨菲定律。

順便說一句,這個問題比僅僅被零除了更糟糕。 10 /10 -200也會溢出。