linux社区爱心援助Linux认证系列教程业界动态站务新闻公司招聘建议留言网址大全LPI专题CISCO专题
设为首页
加入收藏
管理团队
JSP  
JAVA  
PERL  
 您的位置:首页 > article > Linux开发区 > 软件开发 >
栏目导栏
资料搜索
热门文章
·Linux 下 C 语言编程
·Linux下的通用线程池创建
·C++字符串转换篇
·linux C 进程操作篇
·linux上的C/C++编译器gcc/egcs
·linux C 文件权限控制篇
·GCC使用手册
·linux C 接口处理篇
·在Redhat Linux上安装 GCC 编译
·GCC使用指南
·C语言运算符
·Linux下C开发环境的构成和安装
·fopen()函数的参数说明
·GCC使用手册与常用命令
·Scheme 语言介绍
最新文章
·在Ubuntu Linux 8.04上构建GCC
·Linux操作系统下Socket编程地址
·将VC程序移植到Linux系统的几点
·Linux下malloc/free与new/dele
·Linux下用GTK和socket实现简单
·Linux操作系统下让Tomcat启动在
·Linux操作系统中如何编译C程序
·几种常被人们忽略的Linux系统下
·Eclipse编程工具 在Ubuntu下的
·Linux操作系统下的网络地址转换
·老手经验谈:Linux驱动程序开发
·Linux操作系统多线程同步Mutex
·Linux操作系统下C程序语言简易
·Linux系统平台下关于GCC编译及
·解决Linux系统下管道被接受方关
Google
 
C++数据类型的属性与限制
[ 作者:谢启东编…  加入时间:2007-05-22 07:16:16  来自:天极开发 ]
    在C++中,每一种内置的数据类型都拥有不同的属性 ,其中包含的信息对设计程序来说是非常重要的,下面来看一下,<limits>库是怎样有助于访问这些信息的。 XqqLinux联盟
XqqLinux联盟
  C++ 中约有10种截然不同的整数类型及超过3种的浮点类型,而每种数据类型都有不同的数值属性,如数值范围、能表示的最大位数、或各自的精度等等,这些属性对金融、科学、图形、数字信号处理等程序来说是极其重要的。本文讨论使用<limits>库,怎样在程序中获得这些基本数据类型的数值属性。XqqLinux联盟
XqqLinux联盟
  "一个double类型中能存储多少位?","signed long能表示的最大正数是多少?"如果这些问题的答案对你的程序很重要,那么你怎样以一种方便、且系统的方法来得到答案呢?答案就是:使用标准<limits>库。XqqLinux联盟
XqqLinux联盟
  浮点的乐章XqqLinux联盟
XqqLinux联盟
    C++中浮点数据类型精度是有限的,某些与硬件有关的特性导致了浮点数据类型的截断与取整。现在,你就明白为什么2.0/3.0的结果大概是0.66666666666666663了吧,"数字噪音"通常是大多数bug的源头,请看如下例子:XqqLinux联盟
XqqLinux联盟
double d1=2., d2=3.;XqqLinux联盟
d1/=d2; // 2/3XqqLinux联盟
if (d1*10==(20./d2)) //条件本应该是"真"的,但,哎!XqqLinux联盟
{XqqLinux联盟
//永远不可能执行到的代码XqqLinux联盟
do_equal();XqqLinux联盟
}
XqqLinux联盟
   花括号中的代码行永远也不可能执行,因为在 == 两边的表达式结果会有轻微的差别,d1*10的结果是6.6666666666666661,而20./d2的结果是 6.6666666666666670,正是这种浮点算法的截断与近似值导致了此差异的发生。在此,可使用定标整数,但有时这并不是一个妥善的解决办法, 试想有一张计算复数公式的电子表格--它必须使用浮点类型,在这种情况下,小正数(epsilon)常量这个问题就来了,小正数通常为可用给定数据类型的 大于1的最小值与1之差来表示。举例来说,double类型的小正数为:XqqLinux联盟
XqqLinux联盟
#include <iostream>XqqLinux联盟
#include <limits>XqqLinux联盟
using namespace std;XqqLinux联盟
cout << numeric_limits<double>::epsilon( ) << endl; //输出:2.22045e-016
XqqLinux联盟
  为减少if语句中数字噪音带来的影响,可用一个检查两值粗略相等的表达式来代替 == 操作符。如:XqqLinux联盟
XqqLinux联盟
if ( ((d1*10)-(20.0/d2)) <= numeric_limits<double>::epsilon())XqqLinux联盟
{XqqLinux联盟
do_equal();XqqLinux联盟
}
XqqLinux联盟
  如果double类型的(d1*10)-(20.0/d2)结果不大于小正数,那么它几乎为零,因此,两个子表达式结果相等,应用此技巧可有效降低错误的阀值。例如,如果十亿分之一或者更小的数值,对你的程序来说无关紧要,那么可试下以下的技巧:XqqLinux联盟
XqqLinux联盟
const double BILLIONTH=1./1000000000;XqqLinux联盟
if ( ((d1*10)-(20.0/d2)) <= BILLIONTH)
XqqLinux联盟
  此处请记住,小正数是最小的偏差极限。XqqLinux联盟
XqqLinux联盟
  比double更好XqqLinux联盟
XqqLinux联盟
   选择一种浮点数据类型的标准,是它可以在精度无损的情况下最大存储的十进制位数。例如,假设你的程序必须支持到16位的十进制数,那么应该使用 double、long double还是用户自定义类型呢?要解答此问题,可使用numeric_limits::digits10常量,它会告诉你在精度无损情况下某种类型可 表示的最大十进制位数:XqqLinux联盟
XqqLinux联盟
cout<<numeric_limits<double>::digits10<<endl;//输出:15
XqqLinux联盟
  看起来double并不支持这种精度,那么long double呢?XqqLinux联盟
XqqLinux联盟
cout<<numeric_limits<long double>::digits10<<endl; //输出:18
XqqLinux联盟
  对了,它就可以。请注意,digits10对整型数也同样适用:XqqLinux联盟
XqqLinux联盟
cout<<numeric_limits<long>::digits10<<endl; //输出:9
XqqLinux联盟
  最大值与最小值XqqLinux联盟
XqqLinux联盟
  最大值与最小值即是对相应类型调用numeric_limits::max()和numeric_limits:min()所得到的值:XqqLinux联盟
XqqLinux联盟
cout<<numeric_limits<int>::max()<<endl;// 2147483647
XqqLinux联盟
  无限的<limits>XqqLinux联盟
XqqLinux联盟
   在IEC 559规范实现中,浮点数据类型可表示为"不是一个数字"或NaN。NaN是一种特殊的编码,其代表某种非法数字,可由非法指令产生,或意为指示一个不应 被忽略的数值。如果出现在表达式中的NaN没有发出一个"信号",则其为"安静"状态;否则,其为一个发"信号"的NaN。下面的例子检查在目标平台上支 持哪种NaN类型,并把NaN的值赋给一个变量:XqqLinux联盟
XqqLinux联盟
double d=0;XqqLinux联盟
if(numeric_limits<double>::has_quiet_NaN)XqqLinux联盟
d=numeric_limits<double>::quiet_NaN();XqqLinux联盟
else if (numeric_limits<double>::has_signaling_NaN)XqqLinux联盟
d=numeric_limits<double>::signaling_NaN();XqqLinux联盟
else cerr<<"NaN for double isn't supported";
XqqLinux联盟
  无限在此是一种特殊的情况,其通常由被零除或其他操作产生。下例代码检查目标平台上是否定义了一种特殊的无限码,并把此值赋给一个变量:XqqLinux联盟
XqqLinux联盟
float f=0;XqqLinux联盟
if(numeric_limits<float>::has_infinity)XqqLinux联盟
f=numeric_limits<float>::infinity();XqqLinux联盟
else cerr<<"infinity for float isn't supported";

 

Linux联盟收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站Linux论坛讨论
评论】【加入收藏夹】【 】【打印】【关闭
※ 相关链接
 ·Oracle 与 DB2 数据类型分类对应说明  (2007-04-25 11:21:27)
 ·C/C++程序编译步骤详解  (2007-04-24 11:57:48)
 ·用VC++开发Oracle数据库应用程序详解  (2007-04-03 10:20:23)
 ·c/c++ 学习-open 函数  (2007-03-28 11:12:50)
 ·c/c++ 学习-read 函数和 write 函数  (2007-03-28 11:07:55)
 ·Effective C++ 资料整理  (2007-02-16 11:14:41)
 ·在 C/C++中如何构造通用的对象链表  (2006-12-26 11:33:40)
 ·MySQL的数据类型和建库策略  (2006-11-25 11:32:33)
 ·Linux系统编程之C++游戏程序优化  (2006-11-15 10:02:53)