溢出

来源:互联网 发布:天猫dw美工教程 编辑:程序博客网 时间:2024/05/15 23:53

溢出

就是结果值超出了被赋值对象的类型长度。


例如 8 位(1字节)的 char 。根据它有符号还是无符号, 它可以包含最大数127 或 255 。
下面的乘法向一个 char 赋值 256 ,因而导致了溢出:

int main() {    char value = 32;    int ival = 8;    value = ival * value;    //cout << "value: " <<value << endl;    cout << "value: " << static_cast<int>(value) << endl;}

表示256需要9位,因而向value赋值256导致了与其相广联的内存的溢出。value包含的实际值是未定义的,所以在执行时就可能会引起问题。
当用表达式:

        cout << "value: " << value << endl;

试图输出它时,程序输出结果如下:
这里写图片描述
想了一会后,意识到,在ASCIL码集中,0代表空(NULL)字符,所以什么也不会输出。如下特殊表达式:

cout << "value: " << static_cast<int>(value) << endl;

这种情况下,我们吧value转换位一个int类型的对象。这时候程序输出:
这里写图片描述

在本例中,我们改变的不是value相关的值,而是它被输出操作符解释的方式。当它被当作char型时,值会被映射到相关联的ASCIL表上,输出对应的字符;当被当作int时,会直接输出它的值。


这里顺便补充一下,C++支持的四种类型强制转换:

  1. const_cast:去掉对象的const属性的
  2. static:编译器认为可以支持的强转方式,安全性略高
  3. reinterpret_const:类似于C的强转
  4. dynamic_cast:PTTI强制类型转换(run-time type information)

最近经别人介绍看到了《C标准》(The Standard C Library)这本书,(网上很多需要付费下载,找了好久资源的)
在这本书的limits那章提到了与内置类型表示有关的信息,例如一个类型能表示的最大值和最小值,以及怎样使用这些头文件防止溢出(overflow)和下溢(underflow)。

1.在下面给出的值会被适合在#if预处理指令中使用的常量表达式代替。

这里写图片描述

例如,假设在要表示某个值在VAL_MIN和VAL_MAX之间的有符号数据,就可以通过以下代码来防止程序出现翻译错误:

#include <assert.h>#include <limits.h>#if VAL_MIN < INT_MIN || INT_MAX < VAL_MAX#error values out of range#endif

使用

#include <assert.h>#include <limits.h>#if VAL_MIN < INT_MIN || INT_MAX < VAL_MAX    typedef long Val_t;#else    typedef int Val_t;#endif

然后就可以把所有在这个范围中变化的数据对象声明为Val_t类型。程序就会选择效率更高的类型。
这里呢,

/*HANDLE OVERFLOW*/    if(x < log(DBL_MAX))        y = exp(x);    else        ...

这里写图片描述

可以通过使用一个相关的宏来避免计算log(DBL_MAX),就像:

/*HANDLE OVERFLOW*/    if (x <= PLT_MAX_10_EXP)        y = pow(10, x);    else        ...      

(2)下溢
为了避免下溢,一定要保证所有的值都大于DEL_MIN的数值。下溢的结果不像上溢那样损失惨重,但是仍然麻烦很大。IEEE 754浮点算术提供了渐进下溢,减轻了下溢的一些最坏影响。很多浮点的实现都用零值代替一个过小而不能表示的值。这会在除以一个会产生下溢的值是,遇到麻烦。
可以作如下相应的测试:

/*HANDLE UNDERFLOW*/if(log(DBL_MIN) <= x)    y = exp(x);else    ...if(FLT_MIN10_EXP <= x)    y = pow(10, x);else    ...if(FLT_MIN_EXP < n)    y = ldexp(1.0, n);else    ...

(3)有效值丢失
当对两个几乎相等的值相减是就会发生有效值丢失。
一个可以阻止有效值丢失的方法——把一个很小的书和一个很大的数相加。
在加的过程中,较小的数的重要作用就可能体现不出来。

参考资料:
《C++ Primer 3rd Edition》
《C++标准》

原创粉丝点击