C++ Builder 数学函数异常处理 (DOMAIN error 等)

C++ Builder 参考手册 ➙ C++ Builder 数学函数异常处理 (DOMAIN error 等)


一般情况,我们认为 C++ Builder 的 try 非常好用,可是遇到了 cmath 或 math.h 里面的数学函数出错,就无法捕获了,程序弹出类似下面截图的错误提示 (log: DOMAIN error):

数学函数异常:log: DOMAIN error

这是 cmath 或 math.h 里面的数学函数无法正常计算引起的,例如 domain error 定义域错误,就是函数的参数值超过了函数能够处理的范围,例如 log 函数无法计算 0 和负数的对数值,计算 log(-1.0) 的值就会弹出前面截图的对话框。

如果程序里面有大量的计算,不可能每一个函数计算的时候都判断参数是否合理,因为加了很多判断不但让程序复杂了,而且影响计算效率,这时候就需要屏蔽弹出这样的提示框。

屏蔽数学函数弹出出错提示框,需要在程序里面写 C 语言函数 _matherr 和 _matherrl 来捕获异常,这两个函数可以放在项目里面的任何一个 .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 函数计算 -1.0 的对数值就等于 NAN 而不弹出错提示框了:

计算 -1.0 的对数值,不弹出错对话框

计算结果如果等于:
NAN:无法计算的算式的计算结果;
+INF:正无穷大;
-INF:负无穷大。

std::_isnan(x) 函数可以判断浮点数 x 是否为 NAN,即 x 是 NAN 为真;
std::_finite(x) 函数可以判断 x 是否为实数,即 -∞ < x < +∞ 为真;
这两个函数在 #include 里面。

如果计算结果等于 NAN 说明在整个计算过程中,遇到了无法计算的数值,比如 0 除以 0,或者给负数求平方根等。

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 都不是计算结果期望的值,可以用 _finite 函数判断计算结果。

运行结果:计算出错

由于计算过程中,无法计算 -2.0 的平方根,计算结果为 NAN,这个数值不是 -∞ 到 +∞ 之间的实数,所以判断是否为实数的函数 _finite 返回 false,显示输出 "计算出错"。


相关:

  • C++ Builder 浮点数异常处理
  • C++ Builder 浮点型变量和浮点型常量
  • C++ Builder 整型变量和整型常量

C++ Builder 参考手册 ➙ C++ Builder 数学函数异常处理 (DOMAIN error 等)

你可能感兴趣的:(C++ Builder 数学函数异常处理 (DOMAIN error 等))