C++ Builder 串口控件 | C++ Builder 编程技巧 | C++ Builder 操作指南 | C++ Builder 参考手册 | 基础知识 | cfloat 浮点数 | • 浮点数类型 | • 浮点数异常处理 | • _finite, _finitel | • _isinf, _isinfl | • _isnan, _isnanl | • _fpclass, _fpclassl | • _chgsign, _chgsignl | • _copysign, _copysignl | • _logb, _logbl | • _scalb, _scalbl | • _nextafter, _nextafterl | • _clear87, _clearfp | • _control87, _controlfp | • _status87, _statusfp | • _fpreset | cmath 数学函数 | cstdlib 标准库函数 | System 字符串 | System 日期和时间 | System.Math.hpp 数学函数 | 其他数据类型 | VCL 基础类 | VCL 应用程序 | Pictures 图片 | Graphics 绘图 | Additional 控件 | System 控件 | A ~ Z 字母顺序排列的目录 | 网友留言/技术支持 |
|
_fpclass, _fpclassl - 获取浮点数值的类型 |
_fpclass, _fpclassl:获取浮点数值的类型
函数原型:
int _fpclass(double x); |
int _fpclassl(long double x); |
头文件:
#include <cfloat>
命名空间:
std
参数:
x:浮点数
返回值:
值 |
说明 |
_FPCLASS_UNSUP |
不支持的浮点数格式,Unsupported IEEE format。
Win32 定义了这个值,但是经过测试,没发现如何能返回这个值。
Win64 没有定义这个值,并且也不会返回此值。 |
_FPCLASS_SNAN |
Signaling NaN,产生异常的 NAN 值,如果计算出这个结果表明要抛出异常了。
如果计算时产生了异常,是得不到算式的结果的,因为直接跳出了 try { },所以很难得到 Signaling NaN 值。 |
_FPCLASS_QNAN |
Quiet NaN,安静的 NAN 值,无法计算的算式的计算结果。
很容易得到 Quiet NaN:数值 NaN 就是这样的值,函数 std::nan 也可以得到这样的值,0.0 除以 0.0,或者定义域错误,例如给负数开平方 std::sqrt(-1.0) 或取对数 std::log(-2.0) 等得到的值,都是 Quiet NAN。 |
_FPCLASS_NINF |
Negative Infinity,负无穷大,-∞。
负数向上溢出、负数除以 0.0,还有一些函数运算,例如 std::log(0.0) 都会得到负无穷大值。 |
_FPCLASS_NN |
Negative Normal,正常的负数,能够以正常精度表达的负数【注】 |
_FPCLASS_ND |
Negative Denormal,次正常的负数。有效数字向下溢出一部分,可以表达数值,但是无法保证精度了【注】 |
_FPCLASS_NZ |
Negative Zero (-0.0),负零,由负数计算等于零,例如零除以负数,或者负数向下溢出为零。
在判断上,正零和负零认为是相等的,例如 x 等于正零,y 等于负零,if(x==y) 判断为真。 |
_FPCLASS_PZ |
Positive Zero (+0.0),正零,由整数计算等于零,例如零除以正数,或者正数向下溢出为零。
在判断上,正零和负零认为是相等的,例如 x 等于正零,y 等于负零,if(x==y) 判断为真。 |
_FPCLASS_PD |
Positive Denormal,次正常的正数。有效数字向下溢出一部分,可以表达数值,但是无法保证精度了【注】 |
_FPCLASS_PN |
Positive Normal,正常的正数,能够以正常的精度表达的正数【注】 |
_FPCLASS_PINF |
Positive Infinity,正无穷大,+∞。
正数向上溢出、正数除以 0.0,还有一些函数运行,例如 std::pow(0.0,-1.0) 都会得到正无穷大值。 |
注:函数 _fpclass 返回值的问题
• Win32 不会返回 _FPCLASS_SNAN、_FPCLASS_ND、和 _FPCLASS_PD:
_FPCLASS_SNAN:Win32 只要 Signaling NaN 经过赋值传递到其他变量,就变成了 Quiet NaN,所以无法返回这个值;
_FPCLASS_ND:Win32 丢失精度的负数会认为是普通的负数 _FPCLASS_NN;
_FPCLASS_PD:Win32 丢失精度的正数会认为是普通的正数 _FPCLASS_PN;
• Win64 的库有 bug,_FPCLASS_NINF、_FPCLASS_NN、_FPCLASS_ND 和 _FPCLASS_NZ 这些负值都会返回对应的正值:
_FPCLASS_NINF:Win64 负无穷大会返回正无穷大 _FPCLASS_PINF;
_FPCLASS_NN:Win64 普通的负数会返回普通的正数 _FPCLASS_PN;
_FPCLASS_ND:Win64 丢失精度的负数会返回丢失精度的正数 _FPCLASS_PD;
_FPCLASS_NZ:Win64 负零会返回正零 _FPCLASS_PZ。
• 如果必须使用这个函数,并且每种情况都必须判断准确,可以用本站提供的函数:
victor::_fpclass, victor::_fpclassf, victor::_fpclassl
例子:
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
SetExceptionMask(exAllArithmeticExceptions);
}
//---------------------------------------------------------------------------
UnicodeString FpCStr(double x)
{
int fpc = std::_fpclass(x);
switch(fpc)
{
case _FPCLASS_SNAN : return L"_FPCLASS_SNAN" ;
case _FPCLASS_QNAN : return L"_FPCLASS_QNAN" ;
case _FPCLASS_NINF : return L"_FPCLASS_NINF" ;
case _FPCLASS_NN : return L"_FPCLASS_NN" ;
case _FPCLASS_ND : return L"_FPCLASS_ND" ;
case _FPCLASS_NZ : return L"_FPCLASS_NZ" ;
case _FPCLASS_PZ : return L"_FPCLASS_PZ" ;
case _FPCLASS_PD : return L"_FPCLASS_PD" ;
case _FPCLASS_PN : return L"_FPCLASS_PN" ;
case _FPCLASS_PINF : return L"_FPCLASS_PINF" ;
}
return L"_FPCLASS_UNSUP";
}
//---------------------------------------------------------------------------
double Make_SNaN(void)
{
double SNaN;
*(unsigned long long *)&SNaN = 0x7FF0000000000001ull;
return SNaN;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
double z = 0.0;
double a = 2.0;
double b = -2.0;
double e = Make_SNaN();
UnicodeString s;
s.cat_sprintf(L"e = %7.1lg; _fpclass(%7.1lg) = %s\r\n", e , e , FpCStr(e ).c_str());
s.cat_sprintf(L"sqrt(b) = %7.1lg; _fpclass(%7.1lg) = %s\r\n", sqrt(b) , sqrt(b) , FpCStr(sqrt(b) ).c_str());
s.cat_sprintf(L"z/z = %7.1lg; _fpclass(%7.1lg) = %s\r\n", z/z , z/z , FpCStr(z/z ).c_str());
s.cat_sprintf(L"b/z = %7.1lg; _fpclass(%7.1lg) = %s\r\n", b/z , b/z , FpCStr(b/z ).c_str());
s.cat_sprintf(L"b = %7.1lg; _fpclass(%7.1lg) = %s\r\n", b , b , FpCStr(b ).c_str());
s.cat_sprintf(L"2e-308/b = %7.1lg; _fpclass(%7.1lg) = %s\r\n", 2e-308/b, 2e-308/b, FpCStr(2e-308/b).c_str());
s.cat_sprintf(L"z/b = %7.1lg; _fpclass(%7.1lg) = %s\r\n", z/b , z/b , FpCStr(z/b ).c_str());
s.cat_sprintf(L"z/a = %7.1lg; _fpclass(%7.1lg) = %s\r\n", z/a , z/a , FpCStr(z/a ).c_str());
s.cat_sprintf(L"2e-308/a = %7.1lg; _fpclass(%7.1lg) = %s\r\n", 2e-308/a, 2e-308/a, FpCStr(2e-308/a).c_str());
s.cat_sprintf(L"a = %7.1lg; _fpclass(%7.1lg) = %s\r\n", a , a , FpCStr(a ).c_str());
s.cat_sprintf(L"a/z = %7.1lg; _fpclass(%7.1lg) = %s\r\n", a/z , a/z , FpCStr(a/z ).c_str());
Memo1->Lines->Text = s;
}
//--------------------------------------------------------------------------- |
兼容性:
相关链接:
• _finite • _isinf • _isnan • _fpclass • _control87 • SetExceptionMask • _matherr • 浮点数异常处理
|
|
|
|