如果浮点数运算产生了溢出,或者被零除,会抛出异常,这会影响程序的正常运行,通常处理的方法有两种:
• 第一种方法:允许计算结果为 +INF、-INF 和 NAN 这些浮点数值,永远不抛出异常。
• 第二种方法:用 try ... catch 捕获异常,计算结果不会出现 +INF、-INF 和 NAN;
禁用浮点数异常的语句只需要在程序启动的时候执行一次,以后所有的浮点数溢出和被零除等都不抛出异常,计算结果为 +INF、-INF 和 NAN
头文件
#include
#include
64 位 Windows
C++ Builder XE3 及之后的版本
不支持 (缺少库文件)
32 位 Windows
C++ Builder XE2 及之后的版本
所有版本的 C++ Builder
备注
新版本 C++ Builder 需要使用这个方法
老版本 C++ Builder 采用的方法,不支持 64 位
测试程序:
#include
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
SetExceptionMask(exAllArithmeticExceptions);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
double a = 1.0;
double b = -1.0;
double c = 0.0;
double x = a / c;
double y = b / c;
double z = c / c;
Memo1->Lines->Add(L"x = " + FloatToStr(x));
Memo1->Lines->Add(L"y = " + FloatToStr(y));
Memo1->Lines->Add(L"z = " + FloatToStr(z));
}
运行结果:
对于 C++ Builder 来说,和普通的异常一样,用 try ... catch 或 try ... __finally 处理异常。
测试程序:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
try
{
double a = 1.0;
double b = -1.0;
double c = 0.0;
double x = a / c;
double y = b / c;
double z = c / c;
Memo1->Lines->Add(L"x = " + FloatToStr(x));
Memo1->Lines->Add(L"y = " + FloatToStr(y));
Memo1->Lines->Add(L"z = " + FloatToStr(z));
}
catch(Exception &e)
{
MessageBox(Handle, (L"错误:" + e.ClassName() + L"\r\n" + e.Message).c_str(), L"错误信息", MB_OK|MB_ICONEXCLAMATION);
}
}
通过这个测试程序可以看到:
当任何一句代码产生异常,都会从 try { } 里面跳出,转到 catch(){ } 里面,
在 catch 里面,可以通过 Exception &e 得到异常的类型和错误信息。
如果不希望出错之后放弃所有的计算,需要每条语句都写在一个单独的 try ... catch 里面。