C++数据溢出(上溢和下溢)
2023-06-13 09:11:59 时间
当变量的数据类型所提供的位数无法适应某个值时,就会发生溢出(上溢)或下溢。就像往水桶里装水,水满则溢,变量也是这样,如果要存储的值超过了变量所能提供的位数,就会出现问题。
![C++数据溢出(上溢和下溢)](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/07/20/20210720_60f63c7fad1f9.gif)
不妨来看一个例子,假设在一个使用了 2 个字节内存的 short int 类型变量中存储了以下值:
![C++数据溢出(上溢和下溢)](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/07/20/20210720_60f63c7fad1f9.gif)
这是 32 767 的二进制表示,也是能存储在该数据类型中的最大值。这里先不讲负数如何存储的细节,只要知道 short int 数据类型既可以存储正数也可以存储负数就可以了。高阶位(即最左侧位)是 0 的数字被解释为正数,高阶位为 1 的数字则被解释为负数。
如果上面示例中存储的数字加 1,则该变量将变成以下位模式:
![C++数据溢出(上溢和下溢)](http://ytso-blog-oss-img.oss-cn-beijing.aliyuncs.com/wp-content/uploads/2021/07/20/20210720_60f63c7fb7f9d.gif)
但这不是 32 768。相反,它被解释为负数,所以这不是预期的结果。二进制 1 已经 流入 到高阶位的位置,这就是所谓的溢出(上溢)。
同样地,当一个整数变量保存的数值在其数据类型负值范围的最远端(即最小负值),那么当它被减去 1 时,其高位中的 1 将变为 0,结果数将被解释为正数。这是溢出的另一个例子。
除了溢出以外,浮点值还会遇到下溢的情况。当一个值太接近于零时,就可能会发生这种问题,过小的数字需要更多数位的精度来表示它,因而无法存储在保存它的变量中。
下面的程序演示了溢出和下溢:
// This program demonstrates overflow and underflow. #include iostream using namespace std; int main() // Set intVar to the maximum value a short int can hold short short intVar = 32767; // Set floatVar to a number too small to fit in a float float float floatVar = 3.OE-47; // Display intVar cout Original value of intVar intVar endl; // Add 1 to intVar to make it overflow intVar = intVar + 1; cout intVar after overflow intVar endl; // Subtract 1 from intVar to make it overflow again intVar = intVar - 1; cout intVar after 2nd overflow intVar endl; // Display floatVar cout Value of very tiny floatVar floatVar; return 0; }
程序输出结果:
Original value of intVar 32767
intVar after overflow -32768
intVar after 2nd overflow 32767
Value of very tiny floatVar 0
尽管某些系统在出现溢出或下溢时会显示错误信息,但大多数情况下是不会显示的。该变量现在只是保存了不正确的值,而程序还是会继续运行。因此,为每个需要存储值的变量选择恰当的数据类型使其具有足够的位来保存值是非常重要的。
22033.html
html相关文章
- C++多态案例(三)-电脑组装
- C++ 数据抽象与数据封装
- C++多态与虚函数
- c++获取子类窗口句柄位置_C++中各种获取窗口句柄的方法「建议收藏」
- C++ 单例模式_c 单例模式
- c++ auto类型_auto C++
- C++结构体和类的区别_c++有结构体吗
- C++中小数点后几位的表达
- 【Android NDK 开发】JNI 方法解析 ( C/C++ 调用 Java 方法 | 函数签名 | 调用对象方法 | 调用静态方法 )
- mongodb连接池c++ 封装详解大数据
- C++中的健壮指针和资源管理详解编程语言
- C++ vector插入元素(数据)详解
- C++ map插入数据(STL map插入数据)详解
- C++ stable_sort(STL stable_sort)排序算法详解
- C++结构体完全攻略(超详细)
- 表C与MySQL实现有序列表存储(c++ mysql 列)
- C/C++中如何判断某一文件或目录是否存在
- C++中strtok()函数的用法介绍
- C++进程共享数据封装成类实例
- C++基础入门教程(二):数据、变量、宏等
- C++基础入门教程(七):一些比较特别的基础语法总结
- C++操作MySQL大量数据插入效率低下的解决方法
- C++利用stringstream进行数据类型转换实例
- C++输入输出注意事项总结