前言
固然可以使用一个更大范围的数来保存结果并判断是否溢出,但如果已经是系统或语言支撑的最大整数类型了呢?
先给出结论:
对于无符号整数
运算类型 |
溢出类型 |
判断没有溢出 |
注意 |
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。