前言
固然可以使用一个更大范围的数来保存结果并判断是否溢出,但如果已经是系统或语言支撑的最大整数类型了呢?
先给出结论:
对于无符号整数
运算类型 | 溢出类型 | 判断没有溢出 | 注意 |
---|
s=x+y | 可能上溢 | s≥x | 不能使用s-x==y来判断 |
s=x-y | x<y时会下溢 | x>=y | NA |
m=x*y | 可能上溢 | (x==0&&m==0) || (x!=0&&m/x==y) | NA |
m=x/y | 不会溢出 | 1==1 | NA |
对于有符号整数
运算类型 | 溢出类型 | 如何判断 | 注意 |
---|
s=x+y | 可能上溢或下溢 | !((x>=0&&y>=0&&s<0)||(x<0&&y<0&&s>=0)) | NA |
s=x-y | 可能上溢或下溢 | !((x<0&&y>0&&s>=0)||(x>0&&y<0&&s<=0)) | NA |
m=x*y | 可能上溢 | !x || m/x==y | NA |
m=x/y | 不会溢出 | NA | NA |
证明
无符号整数
- s=x+y
两个正整数相加可能会上溢,根据我们给出的判断方法,我们需要证明只要s大于等于x、y中任意一个,则说明没有溢出。
- 我们要证明当s>=x时没有溢出,先讨论x、y的大小:如果x>=y,则s>=x会传递到s>=y,符合加法性质;如果x<y,则要证明当s>=min(x,y)时,依旧能判断是否溢出;
- 使用反证法,我们假设当s>=x时有溢出,则溢出值s’=x+y-MAX,有x+y-MAX>=x,有y>=MAX,当取等号时,y=MAX,x=0,s’=0时,没有溢出但是还是有s>=x,与假设矛盾;如果取大于号,显然与定义矛盾,从而得证。
- 再证明使用s-x==y不能判断是否溢出,我们这里取3位无符号整数,MAX=8,x=4,y=5,则s=x+y-MAX=1发生溢出,但s-x=-3在无符号是5 == y。