信息的表示和处理
信息存储
2.13寻址和字节顺序
-
对象的地址为所使用字节中最小的地址
-
排列一个对象的字节有两个通用的规则
-
大端法
什么是大端法呢,就是把最高有效字节排在前面,对于int x,&x为0x100;
x所存的值为0x01234567
那么我们是如何存储x的值的呢?
答案是0x100->01 0x101->23
0x102->45 0x103->67
2.小端法
对于小端法,我们就不再叙述,因为他与大端法是相反的,他是把最低有效字节排在前面
- 有个有趣的现象,我们发现,虽然浮点数与整数有着截然不同的存储方式,但是其中的有的位是相等的,因为浮点数其实也把整个数给存了下来,只不过它存储了更多的信息,它包括exp,fraction,signature.因此,浮点数所能表示的范围也就必然比不上整数了
2.17 C语言中的位级运算/逻辑运算
2.18 C语言中的移位运算
- 左移
- 右移
- 逻辑右移
- 算数右移(补高位)
需要注意的是,移位运算的优先级甚至没有加法高
2.2 整数表示
2.21整数数据类型
- 这里经常会考int的范围==-2147483648==~2147483647
整数的表示方法:
- 无符号数编码
- 补码编码
- 原码编码:联系补码,第一位是符号位
- 反码编码:与补码类似,只不过第一位的权值位2w-1-1,这样我们零将会有两种表示形式
2.24有符号数与无符号数之间的转换
数值可能会变,但位模式不变change the translation way of the bites!
转换的时候,加减的是2w
- 一个运算中如果出现了无符号数,那么先把所有的操作数转换为无符号数,再进行运算
2.26拓展一个数字的位表示(short->long)
- 无符号数的零拓展
- 补码的符号拓展
2.3 整数的加法
2.31无符号数的加法
无符号数加法x+y= |
---|
x+y(x+y<2w) |
x+y-2w(else) |
无符号数取反-uwx= |
---|
x(x==0) |
2w-x(x>0) |
如何判断无符号数加法的溢出?
2.32补码加法
与无符号数加法不同,补码的加法还有负溢出的情况
x+y |
---|
x+y(不溢出) |
x+y-2w(正溢出) |
x+y+2w(负溢出) |
- 检测补码加法中的溢出
2.34无符号乘法
- 这种乘法其实非常简单,就是我们正常计算的乘法,但是有个问题—溢出,计算机的,做法是,如果我们是w位的乘法,我们在做乘法运算时,最大的数可以到达(2w-1)2,这个数我们甚至需要用到2w位来表示它,可我们只有w位,那没办法,只能把它截断了。
2.35 补码乘法
我们认为,补码乘法与无符号乘法的位级表示是一样的,
因此,我们只需要把一开始作乘法的两个操作数理解为无符号数乘法,然后再把结果由无符号数转换为补码即可。
2.36 乘以常数
- 我们在前面不难发现,乘法的开销比加法减法要大的多,那么我们在是否能用加法、减法、移位运算来解决乘法的问题呢?
许多编译器意识到了这个问题,例如:对于x*14=(x<<3)+(x<<2)+(x<<1)来解决这个问题
2.37 除以2的幂
-
思考一下,我们在做乘法的时候,是“补位”了,并没有改变原来所储存的值,但是如果我们做除法呢?
-
在做除法的时候,我们习惯把结果舍入到零。
然而我们如果只是简单地通过算术右移来得到结果,在被除数为非负数地时候,总是对的,但是如果是负数,我们右移地时候丢弃了一部分权值,使得结果变得更小了,显然不正确
例如11001100>>4=111111001100 ,我们可以看到,因为我们删除了一部分权值为正数的位,导致了整个数变小了,我们应该如何解决这一问题?
偏置量
我们从书上可以得知
(x+(1<<k)-1)>>k
这一代码可以用来计算x/2k,且这一计算值是精确的,前提是我们加了一个Bias==(1<<k)-1;
通过计算,Bias=2w-1
2.4 浮点数
2.41 二进制小数
-
在十进制的小数表示法中d=Σ10i*di
我们在二进制表示小数中,b=Σ2i*bi -
思考一下,我们在十进制中,1/3无法用小数在有限的范围内表示,那么是不是也有二进制小数无法表示的数呢?
小数的二进制表示法只能表示那些能够被写成x*2y的数,其他的数只能近似地表示。
2.42 IEEE浮点表示
- IEEE浮点标准用V=(-1)s ×M× 2E来表示一个数
其中
- s表示符号位
- M表示一个二进制小数,他的范围是1~2-e或者是0 ~ 1-e1
- E的作用是对浮点数加权
将浮点数的位表示划分为三个字段,分别对这些值进行编码:
- 一个单独的符号位S来编码符号s
- k位的阶码字段exp=ek-1…e1e0根据一些规则编码阶码E
- n位小数字段frac=fn-1…f1f0根据一些规则来编码尾数M
那么规则是什么呢?
一、 规格化的值
s | ≠0&&≠255 | f |
---|
- 这是最普遍的情况,只要exp的位不是极端。
- E=e-Bias,其中Bias=2k-1-1(单精度f为127,双精度double为1023)
- M=1+f,有时,我们也叫这种方式为隐含的以1开头表示,因为我们的E总不为0,所以我们总是能够调整阶码,使得M位于(1,2)之间,因此,我们不妨省一位,把开头的1放在外面当作已知。
二、非规格化的
s | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | f |
---|
- E=1-Bias至于为什么不是0-Bias,请思考浮点数的连续性
- M=f
2.44 舍入
因为表示方法限制了浮点数的范围和精度,我们只能用近似的浮点数运算来表示实数的运算,那么我们要用一种系统的方法,来完成这个“近似”。
这里的e表示的是一个非常小的正数。 ↩︎