csapp4
整数运算
无符号加法
当 x+y >= 2^w,实际结果为 s = x+y-2^w
x+y,s = (x+y) % 2^w
检验溢出的方式:如果 s<x,说明溢出
无符号数的非~x = 2^w - x (x>0)
~x=x(x=0)
补码加法
当 x+y >= 2^(w-1), s = x+y-2^w
当 x+y < -2^(w-1),s = x+y+2^w
正溢出的结果是负数,负溢出的结果是正数。
检验溢出的方式:当 x,y>0 而 s<=0 是正溢出;当 x,y<0 而 s>=0 是负溢出
补码的非
当 x = TMin,-x = TMin
当 x ≠ TMin,-x = -x
补码(Two’s Complement)是一种在计算机系统中表示有符号整数的方法。对于一个给定的二进制数,补码是通过以下步骤得到的:
- 取反:将所有的1变为0,所有的0变为1(除了最高位符号位)。
- 加一:将取反后的结果加1。
补码的非(Negative of a Complement)是指对一个数的补码再取补码。具体来说,一个数A的补码的非可以这样得到:
- 取反:将A的补码按位取反(包括符号位)。
- 加一:将取反后的结果加1。
补码非的位级表示:****对每一位求补,结果再加 1
计算补码非的第二种方法:假设 k 是最右边的 1 的位置,对 k 左边的所有位取反
无符号乘法
无符号乘法的积 m = (x*y) % 2^w
补码乘法
补码乘法的积 m = (x*y) % 2^w
乘以常数
大多数机器上,整数乘法需要 10 个或更多的时钟周期,而加法、减法、位级运算和移位只需要 1 个时钟周期
编译器对整数乘法进行优化的方式:用移位和加法或减法运算的组合来代替常数因子的乘法。
左移 k 位等于乘以 2^k
例: x*3= x<<2+x
除以2的幂
除以 2 的幂可以用移位运算来代替,无符号采用逻辑右移,补码采用算术右移
对于有符号数而言,算术右移的结果相当于进行除法运算后向下舍入
浮点数
非常大,非常接近零,近似值计算
二进制小数
小数的二进制表示法都是近似表示,x 可以由形如 2^i + 2^j + … + 2^n 的多项式表示
IEEE 浮点表示
IEEE 浮点标准的表示形式为:V = (-1)^S * M * 2^E
- 符号:S 决定是负数还是正数
- 尾数:M 是一个二进制小数,范围是 1
2-ε 或 01-ε- 阶码:E 的作用是对浮点数加权
不同精度的浮点的尾数和阶码也有所不同
- k 位的阶码字段 e编码 E;float 中 k=8,double 中 k=11
- n 位的小数字段 f 编码 M;float 中 n=23,double 中 n=52
被编码的值可以分成三种情况:
规格化的值:阶码字段即不全为 0 也不全为 1 时属于规格化值
阶码字段解释方式:E = e - (2^(k-1)-1)
小数字段解释方式:M = 1 + f
非规格化的值: 阶码字段全为 0 时属于非规格化形式
特殊值: 阶码字段全为 1
- 小数字段全为 0:表示无穷
- 小数字段非零:表示 NaN(not a number)
舍入
向偶数舍入(向最接近的值舍入):非中间值 (0.5) 四舍五入,中间值向偶数舍入。
向零舍入
向下舍入
向上舍入
浮点运算
IEEE 标准定义 1/-0 = -∞,1/+0 = +∞
浮点运算是可交换不可结合也不可分配的
浮点加法满足加法和乘法上的单调性。如果 a>=b,则 x+a >= x+b
c语言中
int 到 float:不会溢出,可能舍入
int 或 float 到 double:不会溢出也不会舍入
double 到 float:可能溢出和舍入
float 或 double 到 int:向零舍入,很大时可能溢出,很接近零时也可能溢出。当从浮点转换到整数时如果溢出,转变结果都为 [1000],因此一个正浮点可能得到一个负整数