文章目录
无符号加法
考虑两个非负整数x
和y
,满足 0 ≤ x , y < 2 w 0 \le x, y < 2^w 0≤x,y<2w,每个数都能表示为一个w
位的无符号数。如果要计算x+y
,其结果的可能取值范围是 0 ≤ x + y ≤ 2 w + 1 − 2 0 \le x+y \le 2^{w+1}-2 0≤x+y≤2w+1−2,表示该值可能需要w+1
位。如果x+y
的结果又要和别的数做加法,那可能需要更多的位表示运算结果。这种字长膨胀意味着,要想完整地表示运算的结果,我们不能对整型长度做任何限制。
但实际情况是,在C
语言中,整型变量占固定大小的字节和位,当整数运算结果超出了整型变量的表示范围时,计算机运算的结果是截断后的值,与预期值有偏差。
我们定义操作 + w u +^u_w +wu是w
位的无符号加法。
原理:无符号数加法。
对满足 0 ≤ x , y < 2 w 0 \le x,y<2^w 0≤x,y<2w的 x x x和 y y y,有:
x + w u y = { x + y , 0 ≤ x + y ≤ 2 w − 1 x + y − 2 w , 2 w ≤ x + y ≤ 2 w + 1 − 2 \begin{align} x+^u_wy= \begin{cases} x+y,\quad &0 \le x+y \le 2^w -1 \\ x + y-2^w, \quad &2^w \le x+y \le 2^{w+1}-2 \end{cases} \end{align} x+wuy={
x+y,x+y−2w,0≤x+y≤2w−12w≤x+y≤2w+1−2
说一个算术运算溢出,是指完整的整数结果不能被有限的整型长度所表示,产生了高有效位的丢失。
执行C
程序时,系统不会因运算发生溢出而自己报错,因此程序员必须关注该情况。
原理:检测无符号加法中的溢出。
对满足 0 ≤ x , y ≤ 2 w − 1 0 \le x,y \le 2^w-1 0≤x,y≤2w−1的x
和y
,存在 s = ˙ x + w u y s\.=x+^u_wy s=˙x+wuy,当且仅当 s < x s < x s<x, s < y s<y s<y时,运算发生了溢出。
- 证明:当 s < x s < x s<x, s < y s<y s<y时,运算发生了溢出。
因为 x ≥ 0 x\ge 0 x≥0,因此 x + y ≥ y x+y \ge y x+y≥y,因此 s ≥ y s \ge y s≥y,所以当 s < y s<y s<y时,发生运算错误(即溢出)。
因为 y ≥ 0 y \ge0 y≥0,因此 x + y ≥ x x+y \ge x x+y≥x,因此 s ≥ x s \ge x s≥x,所以当 s < x s<x s<x时,发生运算错误(即溢出)。 - 证明:当运算发生溢出时, s < x s < x s<x, s < y s<y s<y。
运算发生溢出时, s = x + y − 2 w s=x+y-2^w s=x+y−2w,因为 y < 2 w y<2^w y<2w,因此 y − 2 w < 0 y-2^w<0 y−2w<0,因此 s < x s<x s<x。
运算发生溢出时, s = y + x − 2 w s=y+x-2^w s=y+x−2w,因为 x < 2 w x<2^w x<2w,因此 x − 2 w < 0 x-2^w<0 x−2w<0,因此 s < y s<y s<y。
对任何一个数 x x x而言,存在 − x -x −x使得 − x + x = 0 -x+x=0 −x+x=0,则称 − x -x −x是 x x x的加法逆元, x x x也是 − x -x −x的加法逆元。加法逆元即取反。
原理:无符号数取反。
对满足 0 ≤ x ≤ 2 w − 1 0 \le x \le 2^w-1 0≤x≤2w−1的x
,其w
位的无符号加法逆元 − w u -^u_w −wu可表示为:
− w u x = { x , x = 0 2