C++数据范例的属性与限制
当前位置:以往代写 > C/C++ 教程 >C++数据范例的属性与限制
2019-06-13

C++数据范例的属性与限制

C++数据范例的属性与限制

在C++中,每一种内置的数据范例都拥有差异的属性,个中包括的信息对设计措施来说长短常重要的,下面来看一下,<limits>库是奈何有助于会见这些信息的。

C++中约有10种截然差异的整数范例及高出3种的浮点范例,而每种数据范例都有差异的数值属性,如数值范畴、能暗示的最大位数、或各自的精度等等,这些属性对金融、科学、图形、数字信号处理惩罚等措施来说是极其重要的。本文接头利用<limits>库,奈何在措施中得到这些根基数据范例的数值属性。

"一个double范例中能存储几多位?","signed long能暗示的最大正数是几多?"假如这些问题的谜底对你的措施很重要,那么你奈何以一种利便、且系统的要领来获得谜底呢?谜底就是:利用尺度<limits>库。

浮点的乐章

C++中浮点数据范例精度是有限的,某些与硬件有关的特性导致了浮点数据范例的截断与取整。此刻,你就大白为什么2.0/3.0的功效或许是0.66666666666666663了吧,"数字噪音"凡是是大大都bug的源头,请看如下例子:

double d1=2., d2=3.;
d1/=d2; // 2/3
if (d1*10==(20./d2)) //条件本应该是"真"的,但,哎!
{
//永远不行能执行到的代码
do_equal();
}

花括号中的代码行永远也不行能执行,因为在 == 双方的表达式功效会有轻微的不同,d1*10的功效是6.6666666666666661,而20./d2的功效是6.6666666666666670,正是这种浮点算法的截断与近似值导致了此差此外产生。在此,可利用定标整数,但有时这并不是一个妥善的办理步伐,试想有一张计较复数公式的电子表格–它必需利用浮点范例,在这种环境下,小正数(epsilon)常量这个问题就来了,小正数凡是为可用给定命据范例的大于1的最小值与1之差来暗示。举例来说,double范例的小正数为:

#include <iostream>
#include <limits>
using namespace std;
cout << numeric_limits<double>::epsilon( ) << endl; //输出:2.22045e-016

为淘汰if语句中数字噪音带来的影响,可用一个查抄两值大致相等的表达式来取代 == 操纵符。如:

if ( ((d1*10)-(20.0/d2)) <= numeric_limits<double>::epsilon())
{
do_equal();
}

假如double范例的(d1*10)-(20.0/d2)功效不大于小正数,那么它险些为零,因此,两个子表达式功效相等,应用此能力可有效低落错误的阀值。譬喻,假如十亿分之一可能更小的数值,对你的措施来说无关紧急,那么可试下以下的能力:

const double BILLIONTH=1./1000000000;
if ( ((d1*10)-(20.0/d2)) <= BILLIONTH)

此处请记着,小正数是最小的毛病极限。

比double更好

选择一种浮点数据范例的尺度,是它可以在精度无损的环境下最大存储的十进制位数。譬喻,假设你的措施必需支持到16位的十进制数,那么应该利用double、long double照旧用户自界说范例呢?要解答此问题,可利用numeric_limits::digits10常量,它会汇报你在精度无损环境下某种范例可暗示的最大十进制位数:

cout<<numeric_limits<double>::digits10<<endl;//输出:15

看起来double并不支持这种精度,那么long double呢?

cout<<numeric_limits<long double>::digits10<<endl; //输出:18

对了,它就可以。请留意,digits10对整型数也同样合用:

cout<<numeric_limits<long>::digits10<<endl; //输出:9

最大值与最小值

最大值与最小值等于对相应范例挪用numeric_limits::max()和numeric_limits:min()所获得的值:

cout<<numeric_limits<int>::max()<<endl;// 2147483647

无限的<limits>

在IEC 559类型实现中,浮点数据范例可暗示为"不是一个数字"或NaN。NaN是一种非凡的编码,其代表某种犯科数字,可由犯科指令发生,或意为指示一个不该被忽略的数值。假如呈此刻表达式中的NaN没有发出一个"信号",则其为"宁静"状态;不然,其为一个发"信号"的NaN。下面的例子查抄在方针平台上支持哪种NaN范例,并把NaN的值赋给一个变量:

double d=0;
if(numeric_limits<double>::has_quiet_NaN)
d=numeric_limits<double>::quiet_NaN();
else if (numeric_limits<double>::has_signaling_NaN)
d=numeric_limits<double>::signaling_NaN();
else cerr<<"NaN for double isn't supported";

无限在此是一种非凡的环境,其凡是由被零除或其他操纵发生。下例代码查抄方针平台上是否界说了一种非凡的无限码,并把此值赋给一个变量:

float f=0;
if(numeric_limits<float>::has_infinity)
f=numeric_limits<float>::infinity();
else cerr<<"infinity for float isn't supported";

    关键字:

在线提交作业