C++ Builder 浮点数异常处理

C++ Builder 参考手册 ➙ C++ Builder 浮点数异常处理


Floating point division by zero.
Floating point overflow.
Invalid floating point operation.

在程序运行中,可能会遇到弹出浮点数错误的提示框,甚至可能会不停的弹出这样的提示框,即 “浮点数被 0 除”、“浮点数溢出”、“无效的浮点数操作” 等:

Floating point division by zero.
Floating point overflow.
Invalid floating point operation.

C++ Builder 对浮点数异常的处理分两种情况:

  1. 抛出异常,默认是这样处理的,就像本文前面描述那样,如果没有放在 try 里面就会直接弹出错误提示框;
  2. 不抛出异常,有异常的算式的计算结果为 NAN,+INF,-INF。

执行如下代码之后,就不抛出浮点数异常了:

std::_control87(MCW_EM, MCW_EM);

SetExceptionMask(exAllArithmeticExceptions);

_control87 需要包含的头文件是 #include
SetExceptionMask 需要包含的头文件是 #include

NAN: 是 not a number (不是数) 的缩写,是无法计算的算式的计算结果;
+INF: 是 +infinity (+∞,正无穷大) 的缩写;
-INF: 是 -infinity (-∞,负无穷大) 的缩写。

例如:
1.0 / 0.0 等于 +INF;
-1.0 / 0.0 等于 -INF;
0.0 / 0.0 等于 NAN。

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

如果 +INF、-INF 和 NAN 都不是计算结果期望的值,可以用 std::_finite 函数判断计算结果。

以下代码演示了屏蔽浮点数异常的有异常的算式的计算结果:

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    SetExceptionMask(exAllArithmeticExceptions);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    double a, b;
    UnicodeString s;

    a = -1.0;
    b = 0.0;
    s.cat_sprintf(L"%g / %g = %g\r\n", a, b, a/b);

    a = 1e300;
    b = 1e-50;
    s.cat_sprintf(L"%g / %g = %g\r\n", a, b, a/b);

    a = 0.0;
    b = 0.0;
    s.cat_sprintf(L"%g / %g = %g\r\n", a, b, a/b);

    Memo1->Lines->Text = s;
}
//---------------------------------------------------------------------------

执行结果为:

屏蔽浮点数异常的有异常的算式的计算结果

-1 / 0 = -INF 是因为任何负数除以 0 都等于负无穷大;
1e+300 / 1e-50 = +INF 是因为计算结果大于浮点数能够表示的最大值;
0 / 0 = -NAN 是因为无法计算 0 除以 0 的值。


相关:

  • C++ Builder 数学函数异常处理 (DOMAIN error 等)
  • C++ Builder 浮点型变量和浮点型常量
  • C++ Builder 整型变量和整型常量

C++ Builder 参考手册 ➙ C++ Builder 浮点数异常处理

你可能感兴趣的:(C++ Builder 浮点数异常处理)