[理解]
這個定理比較容易, 也比較能讓人接受. 不解釋啦.
代碼如下:
/* Determine whether arguments can be added without overflow */
int uadd_ok(unsigned int x, unsigned int y)
{
return !(x+y < x);
}
問題二: 無符號數的減法越界問題
[定理]
[理解]
1. 計算機中沒有減法, x-y = x+(-y), 這裡的-y就是上述的y的加法逆元. 不管是有符號還是無符號, 都是轉換為加法運算. 只是加法逆元的定義不同.
3. C語言保證 -x = ~x+1; 可以驗證這種方式與上面公式等價.
4. s=x-y = x+(-y). 那麼 不會溢出 等價於 y不為0 或者 !uadd_ok(x, -y).
代碼如下:
/* Determine whether argumnts can be substracted without overflow */
int usub_ok(unsigned int x, unsigned int y)
{
return !y || !uadd_ok(x, -y);
}
問題三: 無符號數的乘法越界問題
[定理]
[理解]
等價條件可以相互推導即可.
代碼如下:
/* Determine whether arguments can be multiplied without overflow */
int umul_ok(unsigned int x, unsigned int y)
{
unsigned int p = x * y;
return !x || p/x==y;
}
問題四: 有符號數的加法越界問題
[定理]
對於兩個有符號數x, y. 越界的等價條件是x,y為負數, x+y為正數或者x,y為正數, x+y為負數.
[理解]
這個定理比較容易.
代碼如下:
/* Determine whether arguments can be added without overflow */
int tadd_ok(int x, int y)
{
return !(x<0&&y<0&&x+y>0 || x>0&&y>0&&x+y<0);
}
問題五: 有符號數的減法越界問題
[定理]
[理解]
同無符號的減法一樣, 只是加法逆元的定義不同, 但是位模式是一樣的. C語言可以保證-x=~x+1. 同樣也分兩種情況討論.見代碼.
代碼如下:
/* Determine whether arguments can be subtracted without overflow */
int tsub_ok(int x, int y)
{
#if 0
if (y == INT_MIN)
return x<0;
else
return tadd_ok(x, -y);
#endif
return y==INT_MIN&&x<0 || y!=INT_MIN&&tadd_ok(x, -y);
}
問題六: 有符號數的乘法越界問題
[定理]
完全同無符號的乘法一樣.
代碼如下:
/* Determine whether arguments can be multiplied without overflow. */
int tmul_ok(int x, int y)
{
#if 0
int p = x * y;
return !x || p/x==y;
#endif
return umul_ok(x, y); /* 直接調用 */
}