主页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 字母顺序排列的目录
网友留言/技术支持
victor::_fpclass, victor::_fpclassf, victor::_fpclassl - 获取浮点数值的类型

victor::_fpclass, victor::_fpclassf, victor::_fpclassl:获取浮点数值的类型

函数原型:

int _fpclass(double x);
int _fpclass(float x);
int _fpclass(long double x);
int _fpclassf(float x);
int _fpclassl(long double x);

头文件:

#include <cfloat>

命名空间:

victor

自己写的函数,用来代替 <cfloat> 里面有问题的函数 std::_fpclassstd::_fpclassl

参数:

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) 都会得到正无穷大值。

函数实现:

//---------------------------------------------------------------------------
namespace victor {
//---------------------------------------------------------------------------
int _fpclass(double x) // Copyright © Victor Chen, http://www.cppfans.com/
{
  unsigned long long ullBinary = *(unsigned long long *) &x; // 1,11,52
  int bNegative = (ullBinary & 0x8000000000000000ull) != 0; // 符号位:0正,1负
  if((ullBinary & 0x7FFFFFFFFFFFFFFFull) == 0) // 零值:除了符号位之外其他位都等于零
     return bNegative ? _FPCLASS_NZ : _FPCLASS_PZ; // 负数 ? 负零 : 正零
  if((ullBinary & 0x7FF0000000000000ull) == 0) // 指数等于零为零或丢失精度的浮点数
     return bNegative ? _FPCLASS_ND : _FPCLASS_PD;
  if((ullBinary & 0x7FF0000000000000ull) == 0x7FF0000000000000ull) // 指数全一 NAN 或 INF
   {
     if((ullBinary & 0x000FFFFFFFFFFFFFull) == 0) // 尾数等于零为 INF
        return bNegative ? _FPCLASS_NINF : _FPCLASS_PINF;
     else // 尾数不等于零,尾数的符号位区分安静 NAN 和异常 NAN
        return (ullBinary & 0x0008000000000000ull) ? _FPCLASS_QNAN : _FPCLASS_SNAN;
   }
  return bNegative ? _FPCLASS_NN : _FPCLASS_PN; // 特殊值处理完了,剩下的就是普通的值
}
//---------------------------------------------------------------------------
int _fpclassf(float x) // Copyright © Victor Chen, http://www.cppfans.com/
{
  unsigned long ulBinary = *(unsigned long *) &x; // 1,8,23
  int bNegative = (ulBinary & 0x80000000ul) != 0; // 符号位:0正,1负
  if((ulBinary & 0x7FFFFFFFul) == 0) // 零值:除了符号位之外其他位都等于零
     return bNegative ? _FPCLASS_NZ : _FPCLASS_PZ; // 负数 ? 负零 : 正零
  if((ulBinary & 0x7F800000ul) == 0) // 指数等于零为零或丢失精度的浮点数
     return bNegative ? _FPCLASS_ND : _FPCLASS_PD;
  if((ulBinary & 0x7F800000ul) == 0x7F800000ul) // 指数全一 NAN 或 INF
   {
     if((ulBinary & 0x007FFFFFul) == 0) // 尾数等于零为 INF
        return bNegative ? _FPCLASS_NINF : _FPCLASS_PINF;
     else // 尾数不等于零,尾数的符号位区分安静 NAN 和异常 NAN
        return (ulBinary & 0x00400000ul) ? _FPCLASS_QNAN : _FPCLASS_SNAN;
   }
  return bNegative ? _FPCLASS_NN : _FPCLASS_PN; // 特殊值处理完了,剩下的就是普通的值
}
//---------------------------------------------------------------------------
int _fpclassl(long double x) // Copyright © Victor Chen, http://www.cppfans.com/
{
  #if defined(_M_IX86)
  unsigned char *pBinary = (unsigned char *)&x; // 10 个字节的 80-bit double 值,x86 架构为小端存储
  unsigned long long ullSignificand = 0x7FFFFFFFFFFFFFFFull & *(unsigned long long *)(pBinary); // 尾数
  unsigned long ulExponent = 0x7FFF8000ul & *(unsigned long *)(pBinary+6); // 指数
  int bNegative = (0x80 & *(pBinary+9)) != 0; // 是否为负数。符号位:0正,1负

  if((ullSignificand==0) && (ulExponent==0)) // 零值:尾数和指数都等于零
     return bNegative ? _FPCLASS_NZ : _FPCLASS_PZ; // 负数 ? 负零 : 正零
  if(ulExponent == 0) // 指数等于零:丢失精度的数值
     return bNegative ? _FPCLASS_ND : _FPCLASS_PD; // 负数 ? 丢失精度的负数 : 丢失精度的正数
  if(ulExponent == 0x7FFF8000ul) // 指数全一 NAN 或 INF
   {
     if(ullSignificand == 0) // 尾数等于零为无穷大
        return bNegative ? _FPCLASS_NINF : _FPCLASS_PINF; // 负数 ? 负无穷大 : 正无穷大
     else // 尾数不等于零,尾数的符号位区分安静 NAN 和异常 NAN
        return (ullSignificand & 0x4000000000000000ull) ? _FPCLASS_QNAN : _FPCLASS_SNAN;
   }
  return bNegative ? _FPCLASS_NN : _FPCLASS_PN; // 特殊值处理完了,剩下的就是普通的值
  #else
  return _fpclass((double)x); // 64-bit double
  #endif
}
//---------------------------------------------------------------------------
int _fpclass(float x) // Copyright © Victor Chen, http://www.cppfans.com/
{
  return _fpclassf(x); // 32-bit float
}
//---------------------------------------------------------------------------
int _fpclass(long double x) // Copyright © Victor Chen, http://www.cppfans.com/
{
  #if defined(_M_IX86)
  return _fpclassl(x); // 80-bit long double
  #else
  return _fpclass((double)x); // 64-bit long double
  #endif
}
//---------------------------------------------------------------------------
} // namespace victor
//---------------------------------------------------------------------------

例子:

函数 std::_fpclass 的例子

把 std::_fpclass 换成 victor::_fpclass 就可以了

兼容性:

函数 \ C++ Builder 编译器 bcc32 clang32 clang64
victor::_fpclass
victor::_fpclassf
victor::_fpclassl

相关链接:

_finite_isinf_isnan_fpclass_control87SetExceptionMask_matherr浮点数异常处理

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

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