2018-10-28 CSAPP 第二章读书笔记part2
2.2 整数表示
2.2.1 整数数据类型
有符号
无符号
负数比正数大一(有一个-0被表示为最小的那个负数)
2.2.2 无符号数的编码
性质:双射
数学术语双射是指一个函数f有两面:他将数值x映射为数值y,即y=f(x),但它也可以反向操作,因为对每一个y而言,都有唯一一个数值x使得f(x)=y。
2.2.3 补码编码
用这种方式理解补码,是一种新的不错的思路
很容易算出范围。不用思考转成原码。
对于许多应用,我们还希望表示负数值。最常见的有符号数的计算机表示方式就是补码形式。在这个定义中,将字的最高位解释为负权。用B2Tw表示。
2.2.4有符号数和无符号数之间的转换
2.2.5 C语言中的有符号数和无符号数
默认为有符号,如果需要无符号某尾+U,例:12345U
2.2.6 扩展一个数字的位表示
对于一个无符号数转为更大的数据类型
只需要简单地在表示的开头添加0,这种运算称为零扩展
对于有符号的数,即补码
进行符号扩展(sign extension),就是添加最高有效位的值
对比逻辑右移,和算术右移
2.2.7 截断数字
截断一个数到k位,即舍去w-k的高位。
对于无符号数截断x它到k位的结果相当于
B2U([Xk-1,Xk-2,….x0])=B2U([Xw-1,Xw-2…x0]) mod 2^k
对于有符号的数x。
截断的时候还是当做无符号的数看
B2T([Xk-1,Xk-2,….x0])=U2T(B2U([Xw-1,Xw-2…x0]) mod 2^k
)
建议
在大多数情况下使用有符号整数
java中只支持有符号整数,>>算数右移,>>>才是逻辑右移
2.3 整数运算
2.3.1 无符号加法
x+y = (x+y) mod 2^k
溢出会舍去
阿贝尔群,群论。
2.3.2 补码加法
大多数计算机使用同样的机器指令来执行有符号和无符号之和。
x(有符号+)y= U2T(T2U(x+y) mod 2^w)
先计算x+y
将x+y转换为无符号类型z。
p=z mod 2^w
附.(或者直接对x+y的二进制表示进行截断得到p)
将p用有符号类型表示
正溢出,正常,负溢出。
2.3.3 补码的非
因为正负区间的不一致
所以最小的那个负数的相反数逆元还是最小的那个负数。
对于任意整数x。-x和~x+1得到的结果完全一样。
2.3.4 无符号乘法
只取低w位表示的值,其余截断
2.3.5 补码乘法
对于无符号和补码乘法,乘法运算的位级表示都是一样的,是同一条指令。
无符号和补码相乘出来的两个数的低W位 永远相等。证明见书。
2.3.6 乘常数
因为乘法速度太慢,机器可能会用(加法,减法,移位)来代替乘法。
2.3.7 除以2的幂
对于无符号类型或整数,直接右移不会有任何问题。
对于负数,最后的值为-48.3,会舍入成 -49,而不是-48.
解决方法是偏置
原理:
C语言
(x<0 ? (x+(1<<k)-1):x)>>k
等价于x/pwr2k ,pwr2k=2^k
2.4 浮点数
在1985年,IEEE标准754退出,这是一个仔细制订的表示浮点数及其运算的标准。
2.4.1 二进制小数
2.4.2IEEE浮点表示
情况1:规格化的值
情况2:非规格化的值
情况3:特殊值
2.4.5 浮点运算
2.5 小结
计算机将信息编码为位,通常组织成字节序列。有不同的编码方式用来表示整数、实数和字符串。不同的计算机模型在编码数字和多字节数据中的字节顺序时使用不同的约定。
大多数及其对整数使用补码编码,而对浮点数使用IEEE标准754编码。
浮点表示通过数字编码为 的形式来近似地表示实数。最常见的浮点表示方式是由IEEE标准754定义的。它提供了几种不同的精度,最常见的是单精度和双精度,IEEE浮点也能够表示特殊值无穷大、无穷小和NaN。