簡體   English   中英

除零預防

[英]Divide by zero prevention

什么是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

1.#INF是正無窮大。 當你將正浮點數除以零時,你會得到它(如果你將浮點數零本身除以零,那么結果將是“不是數字”)。

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

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

為什么正整數轉換為整數是最小的整數,我不知道。

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

它不一定。 在浮點時,標准是驚人的備用。 現在大多數系統都使用IEEE浮點標准,並且表示除以零的默認操作是返回±無窮大而不是崩潰。 您可以通過啟用適當的浮點異常使其崩潰。

注意:浮點異常模型和C ++異常模型的唯一共同點是“異常”一詞。 在我工作的每台機器上,浮點異常不會引發C ++異常。

還有,如何防止0分裂的任何好主意?

  1. 簡單回答:不要這樣做。
    這是其中一個“博士,醫生,當我這樣做時疼!” 各種情況。 所以不要這樣做!

  2. 確保除數不為零。
    對用戶輸入的除數進行完整性檢查。 始終過濾用戶輸入以獲得理智。 當數量應該是數百萬時,用戶輸入值為零將導致除溢出之外的各種破壞。 對中間值進行健全性檢查。

  3. 啟用浮點異常。
    讓默認行為允許錯誤(這些幾乎總是錯誤)經過不加檢查是恕我直言,這是標准委員會的一個重大錯誤。 使用默認值,那些無窮大而非數字最終會將所有內容變為Inf或NaN。
    默認應該是在其軌道中停止浮點錯誤,並允許選項允許發生1.0 / 0.0和0.0 / 0.0之類的事情。 情況並非如此,因此您必須啟用這些陷阱。 這樣做,你可以經常在短時間內找到問題的原因。

  4. 編寫自定義除法,自定義乘法,自定義平方根,自定義正弦,...函數。
    不幸的是,這是許多安全關鍵軟件系統必須采用的途徑。 這是一種皇室的痛苦。 選項#1已經出局,因為它只是一廂情願的想法。 選項#3已淘汰,因為系統無法崩潰。 選項#2仍然是一個好主意,但它並不總是有效,因為糟糕的數據總是有一種偷偷摸摸的方式。這是墨菲定律。

順便說一下,這個問題比僅僅除零更糟糕。 1010分之200-200也會溢出。

您通常會檢查以確保您沒有除以零。 除非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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM