主页C++ Builder 资料C++ Builder 参考手册cfloat 浮点数_fpclass, _fpclassl
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;
}
//---------------------------------------------------------------------------

兼容性:

函数 \ C++ Builder 编译器 bcc32 clang32 clang64
_fpclass √【 √【 √【
_fpclassl √【 √【 √【

相关链接:

_finite_isinf_isnan_fpclass_control87SetExceptionMask_matherr浮点数异常处理

◤上一页:_isnan, _isnanl下一页:_chgsign, _chgsignl

C++ 爱好者 -- Victor Chen 的个人网站 www.cppfans.com 辽ICP备11016859号