首页 > 代码库 > 准确认识算数溢出

准确认识算数溢出

  说明:本文中的代码使用C语言描述

  算数溢出:给指定数据类型的变量赋值超出其取值范围的值将导致算数溢出

  以下代码你认为会输出什么结果?

1-1

1 #include <stdio.h>
2 
3 int main(void) {
4     unsigned short s = -1;
5     printf("s = %d");
6     return 0;
7 }

1-2

#include <stdio.h>

int main(void) {
    unsigned short s = 65545;
    printf("s = %d");
    return 0;
}

  对于1-1代码段,我们期望的输出是:s = -1

  对于1-2代码段,我们期望的输出是:s = 65545

  可事实上的输出分别是:65535 和 9

  为什么会是这样的结果呢?其实结果很简单

  •   首先short类型用2字节也就是16位存储整数,unsigned short表示变量s存储的是无符号整数
  •   unsugned short的取值范围是0~216-1(0~65535)
  •   我们把这个范围的无符号整数想象成从0开始到65535结束的一条线,如果让这条线首尾相接就类似闹钟的表盘
  •   因此,给变量赋值该取值范围内的任何一个值都不会发生溢出,
  •   赋值类似于波动表盘上的指针到指定的刻度,当然指针有顺时针和逆时针的区别(这就是算数溢出的本质原因)
  •   当我们给变量s赋值-1的时候,相当于将指针逆时针调整一个格子,也就是调整到了最末端,即65535
  •   而当我们为s赋值65545的时候,相当于闹钟转了完整的一圈后有多走了10个格子,因为起始点是0,因此得到的结果是10-1=9

  附图如下:

  1-1图

  技术分享

  1-2图

  技术分享

 

准确认识算数溢出