dzxo.com - 零点资讯网

投递文章  投稿指南 RSS订阅 网站通告:
搜索: 您的位置主页>编程语言>C/C++>阅读资讯:C++数据类型的属性与限制

C++数据类型的属性与限制

2008-01-14 11:59:21   来源:零点IT资讯网   作者:ADMIN   【 评论:0
     在C++中,每一种内置的数据类型都拥有不同的属性,其中包含的信息对设计程序来说是非常重要的,下面来看一下,%26lt;limits%26gt;库是怎样有助于访问这些信息的。   C++中约有10种截然不同的整数类型及超过3种的浮点类型,而每种数据类型都有不同的数值属性,如数值范围、能表示的最大位数、或各自的精度等等,这些属性对金融、科学、图形、数字信号处理等程序来说是极其重要的。本文讨论使用%26lt;limits%26gt;库,怎样在程序中获得这些基本数据类型的数值属性。  "一个double类型中能存储多少位?","signed long能表示的最大正数是多少?"如果这些问题的答案对你的程序很重要,那么你怎样以一种方便、且系统的方法来得到答案呢?答案就是:使用标准%26lt;limits%26gt;库。  浮点的乐章  C++中浮点数据类型精度是有限的,某些与硬件有关的特性导致了浮点数据类型的截断与取整。现在,你就明白为什么2.0/3.0的结果大概是0.66666666666666663了吧,"数字噪音"通常是大多数bug的源头,请看如下例子: double d1=2., d2=3.;d1/=d2; // 2/3if (d1*10==(20./d2)) //条件本应该是"真"的,但,哎!{//永远不可能执行到的代码do_equal();}  花括号中的代码行永远也不可能执行,因为在 == 两边的表达式结果会有轻微的差别,d1*10的结果是6.6666666666666661,而20./d2的结果是6.6666666666666670,正是这种浮点算法的截断与近似值导致了此差异的发生。在此,可使用定标整数,但有时这并不是一个妥善的解决办法,试想有一张计算复数公式的电子表格--它必须使用浮点类型,在这种情况下,小正数(epsilon)常量这个问题就来了,小正数通常为可用给定数据类型的大于1的最小值与1之差来表示。举例来说,double类型的小正数为: #include %26lt;iostream%26gt;#include %26lt;limits%26gt;using namespace std;cout %26lt;%26lt; numeric_limits%26lt;double%26gt;::epsilon( ) %26lt;%26lt; endl; //输出:2.22045e-016  为减少if语句中数字噪音带来的影响,可用一个检查两值粗略相等的表达式来代替 == 操作符。如: if ( ((d1*10)-(20.0/d2)) %26lt;= numeric_limits%26lt;double%26gt;::epsilon()){do_equal();}  如果double类型的(d1*10)-(20.0/d2)结果不大于小正数,那么它几乎为零,因此,两个子表达式结果相等,应用此技巧可有效降低错误的阀值。例如,如果十亿分之一或者更小的数值,对你的程序来说无关紧要,那么可试下以下的技巧: const double BILLIONTH=1./1000000000;if ( ((d1*10)-(20.0/d2)) %26lt;= BILLIONTH)  此处请记住,小正数是最小的偏差极限。  比double更好  选择一种浮点数据类型的标准,是它可以在精度无损的情况下最大存储的十进制位数。例如,假设你的程序必须支持到16位的十进制数,那么应该使用double、long double还是用户自定义类型呢?要解答此问题,可使用numeric_limits::digits10常量,它会告诉你在精度无损情况下某种类型可表示的最大十进制位数: cout%26lt;%26lt;numeric_limits%26lt;double%26gt;::digits10%26lt;%26lt;endl;//输出:15  看起来double并不支持这种精度,那么long double呢? cout%26lt;%26lt;numeric_limits%26lt;long double%26gt;::digits10%26lt;%26lt;endl; //输出:18  对了,它就可以。请注意,digits10对整型数也同样适用: cout%26lt;%26lt;numeric_limits%26lt;long%26gt;::digits10%26lt;%26lt;endl; //输出:9  最大值与最小值  最大值与最小值即是对相应类型调用numeric_limits::max()和numeric_limits:min()所得到的值: cout%26lt;%26lt;numeric_limits%26lt;int%26gt;::max()%26lt;%26lt;endl;// 2147483647  无限的%26lt;limits%26gt;  在IEC 559规范实现中,浮点数据类型可表示为"不是一个数字"或NaN。NaN是一种特殊的编码,其代表某种非法数字,可由非法指令产生,或意为指示一个不应被忽略的数值。如果出现在表达式中的NaN没有发出一个"信号",则其为"安静"状态;否则,其为一个发"信号"的NaN。下面的例子检查在目标平台上支持哪种NaN类型,并把NaN的值赋给一个变量: double d=0;if(numeric_limits%26lt;double%26gt;::has_quiet_NaN)d=numeric_limits%26lt;double%26gt;::quiet_NaN();else if (numeric_limits%26lt;double%26gt;::has_signaling_NaN)d=numeric_limits%26lt;double%26gt;::signaling_NaN();else cerr%26lt;%26lt;"NaN for double isn't supported";  无限在此是一种特殊的情况,其通常由被零除或其他操作产生。下例代码检查目标平台上是否定义了一种特殊的无限码,并把此值赋给一个变量: float f=0;if(numeric_limits%26lt;float%26gt;::has_infinity)f=numeric_limits%26lt;float%26gt;::infinity();else cerr%26lt;%26lt;"infinity for float isn't supported";
Tags:  
责任编辑:
  • 请文明参与讨论,禁止漫骂攻击。 用户名:新注册) 密码: 匿名:
    评论总数:0 [ 查看全部 ] 网友评论
    关于我们 - 联系我们 - 广告服务 - 法律声明 - RSS订阅 - 网站地图 - 返回顶部