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 <cfloat> 里面。

如果计算结果等于 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 数学函数异常处理 (DOMAIN error 等)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 在编程中我们总要进行一些数学运算以及数字处理,尤其是浮点数的运算和处理,这篇文章主要介绍C语言下的数学库。而其他语...
    欧阳大哥2013阅读 5,563评论 0 12
  • C++ Builder 参考手册 ➙ C++ Builder 浮点数异常处理 Floating point div...
    玄坴阅读 3,514评论 1 2
  • PHP常用函数大全 usleep() 函数延迟代码执行若干微秒。 unpack() 函数从二进制字符串对数据进行解...
    上街买菜丶迷倒老太阅读 1,506评论 0 20
  • 总结了一些开发中常用的函数: usleep() //函数延迟代码执行若干微秒。 unpack() //函数从二进制...
    ADL2022阅读 546评论 0 3
  • 第一章 前端三大语言:HTML(专门编写网页内容)、CSS(编写网页样式)、JS(专门编写网页交互行为) 能简写尽...
    fastwe阅读 1,203评论 0 0

友情链接更多精彩内容