C++ Builder 參考手冊 ? C++ Builder 數(shù)學函數(shù)異常處理 (DOMAIN error 等)
一般情況卖陵,我們認為 C++ Builder 的 try 非常好用赁濒,可是遇到了 cmath 或 math.h 里面的數(shù)學函數(shù)出錯挣菲,就無法捕獲了苍柏,程序彈出類似下面截圖的錯誤提示 (log: DOMAIN error):
這是 cmath 或 math.h 里面的數(shù)學函數(shù)無法正常計算引起的芋类,例如 domain error 定義域錯誤哩牍,就是函數(shù)的參數(shù)值超過了函數(shù)能夠處理的范圍,例如 log 函數(shù)無法計算 0 和負數(shù)的對數(shù)值倘待,計算 log(-1.0) 的值就會彈出前面截圖的對話框疮跑。
如果程序里面有大量的計算,不可能每一個函數(shù)計算的時候都判斷參數(shù)是否合理凸舵,因為加了很多判斷不但讓程序復(fù)雜了祖娘,而且影響計算效率,這時候就需要屏蔽彈出這樣的提示框啊奄。
屏蔽數(shù)學函數(shù)彈出出錯提示框渐苏,需要在程序里面寫 C 語言函數(shù) _matherr 和 _matherrl 來捕獲異常,這兩個函數(shù)可以放在項目里面的任何一個 .c 或 .cpp 文件里面菇夸。
#ifdef __cplusplus
extern "C" {
#endif
int _matherr(struct _exception *e)
{
return 1;
}
int _matherrl(struct _exceptionl *e)
{
return 1;
}
#ifdef __cplusplus
}
#endif
例如用上面代碼的方法來捕獲異常琼富,用 log 函數(shù)計算 -1.0 的對數(shù)值就等于 NAN 而不彈出錯提示框了:
計算結(jié)果如果等于:
NAN:無法計算的算式的計算結(jié)果庄新;
+INF:正無窮大鞠眉;
-INF:負無窮大。
std::_isnan(x) 函數(shù)可以判斷浮點數(shù) x 是否為 NAN择诈,即 x 是 NAN 為真凡蚜;
std::_finite(x) 函數(shù)可以判斷 x 是否為實數(shù),即 -∞ < x < +∞ 為真吭从;
這兩個函數(shù)在 #include <cfloat> 里面朝蜘。
如果計算結(jié)果等于 NAN 說明在整個計算過程中,遇到了無法計算的數(shù)值涩金,比如 0 除以 0谱醇,或者給負數(shù)求平方根等。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
double x = 1.0/std::sqrt(-2.0);
if(std::_finite(x))
Memo1->Text = x;
else
Memo1->Text = L"計算出錯";
}
如果 +INF步做、-INF 和 NAN 都不是計算結(jié)果期望的值副渴,可以用 _finite 函數(shù)判斷計算結(jié)果。
由于計算過程中全度,無法計算 -2.0 的平方根煮剧,計算結(jié)果為 NAN,這個數(shù)值不是 -∞ 到 +∞ 之間的實數(shù),所以判斷是否為實數(shù)的函數(shù) _finite 返回 false勉盅,顯示輸出 "計算出錯"佑颇。
相關(guān):
C++ Builder 參考手冊 ? C++ Builder 數(shù)學函數(shù)異常處理 (DOMAIN error 等)