对于初学者来说,C语言的整数溢出可能一开始可能会不好理解。对于一个字节的 unsignde char类型和signed char 类型。赋值一个超出其存储范围的数值时,

其真实存储的数值并不等于我们赋值的数据。要弄清整数溢出问题,首先必须清晰计算机中数值都是以补码形式存储的,要会原码、反码和补码的转换。

下面分有符整数溢出和无符整数溢出分析。

 

一、有符整型溢出

 比如下面这个程序,输出不是129而是-127。

整数溢出怎么处理 python 整数型溢出_整数溢出怎么处理 python

整数溢出怎么处理 python 整数型溢出_补码_02

 

我们知道对于有符整型(signed char)它的存储范围为[-128,127],129已经超出向上溢出了。129的机器码为【1000 0001】,计算机会取这八位作为补码存储。

补码【1000 0001】是个负数,求其原码减少1再对数值位取反可得到其原码为【1111 1111】,这个值就是-127(最高位为符号位1,代表负数)。也可以把[-128,127]

看作汽车里程表,当向上超出时就重新从起点开始。129-127 = 2,从新从-128开始这个值就是-(128-2+1) = -127。

再举一个列子,下面这个程序输出的结果为-112而不是400,同样的分析可得出结果。

整数溢出怎么处理 python 整数型溢出_整型_03

整数溢出怎么处理 python 整数型溢出_整型_04

400的机器码为【0000 0001 1001 0000】(2^8+2^7+2^4),计算机会取出低八位【1001 0000】作为补码进行存储,作为补码这明显是个负数,我们减1再对数值位取反可以得到其原码

为【1111 0000】,这个数是-112(2^6+2^5+2^4)。用循环思想也可以验证, 400超出上限400-127 -256 = 17,所以为-【128-17+1】 =  -112。一般我们在将int型数据赋给char型变量的时候

编译器也会发出警告如下:warning: overflow in conversion from 'int' to 'signed char' changes value from '400' to '-112' [-Woverflow]|。

 

二、无符整型溢出

  无符整型溢出就简单多了,因为正数的补码和原码一致。道理也是一样的,这里举一个简单例子分析一下。下面的程序输出结果不是288,而是32。

整数溢出怎么处理 python 整数型溢出_整型_05

整数溢出怎么处理 python 整数型溢出_整型_06

我们知道unsigned char一个字节存储值的范围是[0,255],288明显已经向上溢出了。288的机器码为【0000 0001 0010 0000】(2^8+2^5),计算机取出低八位【0010 0000】作为补码

,正数补码就是原码,这个数就是32,循环思想也可验证。同样的编译器也会发出相关警告:warning: unsigned conversion from 'int' to 'unsigned char' changes value from '288' to '32' [-Woverflow]|

  整型溢出问题,只要对于计算机数值存储形式(补码)和补码原码转换有了解就不难理解了。