整数算术溢出问题的分析

    这篇对整数的一些基本运算产生的溢出问题进行分析。函数

  当你进行加减乘除运算的时候,若是这个数字很大,运算产生的结果就可能会出乎你最初设计程序的预料,这对程序来讲是一种很可怕的漏洞,这让一些恶意的访问者对程序做出一些破坏性的事情,这样形成的危害多是很大的。spa

这里先定义一些宏定义做为返还值:设计

 

#define OVERFLOW 1      //算术溢出(正溢出)
#define NOT_OVERFLOW 0             //未溢出
#define NEGATIVE_OVERFLOW -1      //负溢出

 

当进行无符号整数加法计算的时候。code

  无符号整数的范围是 0 ≤ x  UMax ,UMax = 2w - 1 (w是当前类型的位数) ,若是两个数相加的结果小于任何一个数,那么就能够判断算术溢出。判断的代码以下:
blog

 

int uadd_ok(unsigned x, unsigned y)
{
    unsigned uadd=x+y;
    if( uadd < x || uadd < y)
        return OVERFLOW;
        
    return NOT_OVERFLOW;
}

 

当进行有符号整数加法计算的时候。get

  有符号整数的范围是 TMin ≤ x ≤ TMax TMin = -2w-1 ,TMax = 2w-1 - 1 那么为什TMax的绝对之为何会比TMin的绝对之小一,那么假设 w= 4 观察一下。由于有符号数的最高位是符号位,因此TMax的最高位就是 0 ,为了让数字更大那么其他就应该是 1 ,那么 TMax (4) = 0111 = 22+21+20=23-1=2w-1-1。有符号数的负数部分通常都是用补码表示的 TMin 最高位就须要是 1 由于只有最高位是表明负数,其他位都是正数,最后这个数的值是各个位的值的加和获得的,因此其他位都须要是 0 ,那么 TMin(4)=1000= -23 = -2w-1 。那么判断有符号数加法的代码一种错误以下,它利用了阿贝尔群得知补码加法的时候,(x+y)-y=y 在溢出的状况下是成立的。因此就有可能出现以下的代码:
it

 

int tadd_ok(int x, int y)
{
     int sum=x+y;
     return (sum - y == y) && (sum - x == y) ; 
}    

 

可是这个代码的返回值永远是 1, 由于在不溢出的状况下表达式成立是显而易见的。class

因此就须要考虑多方面的因素了,两个数都大于零的时候,若是结果是负数那么可判断溢出。若是两个数都是负数,结果为正数那么判断也溢出。程序

代码以下:di

 

int tadd_ok(int x, int y)
{
    int tadd=x+y;
    if( x > 0 && y > 0 )
        if( tadd < 0 )
            return OVERFLOW;
    
    if( x < 0 && y < 0 )
        if( tadd >= 0 )
            return NEGATIVE_OVERFLOW;
    
    return NOT_OVERFLOW;
}

 

当进行有符号减法运算的时候。

  这个时候你可能想像这样调用写好的 tadd_ok( x, -y );  函数,可是实际上在一些状况下这是错误的,由于 TMin = -TMin ,这样你想要的 -TMin 就没有变成 | TMin | 却变成了TMin 因此就须要增长一些判断。

代码以下:

 

int tsub_ok(int x, int y)
{
    if( y != 0 && y == -y )
    {
        if( x >= 0 )
            return OVERFLOW;
        return NOT_OVERFLOW;
    }
    return tadd_ok(x,-y);
}

 

 

当是乘法运算的时候不论有符号仍是无符号,溢出的部分都是直接截掉的。

  固然乘法是可使用 ( x * y ) / x = y 进行判断的由于溢出的时候这是不成立的,固然你须要保证 x , y 不是零 ,若是是零做为除数是不合理的。

因此能够写出以下代码:

 

int tmult_ok(int x, int y)
{
    int tmult=x*y;
    if( x != 0 && y!= 0 )
    {
        if( tmult / x == y )
            return NOT_OVERFLOW;
        return OVERFLOW;
    }
    return NOT_OVERFLOW;
}
相关文章
相关标签/搜索