深入了解计算机原理--第一章
二、信息的表示和表达
2.1 信息存储
2.1.1 十六进制表示法
转化为二进制需要从右到左每4分为一组转换(不足补0)
十进制和十六进制互选转换
十进制除16倒取余
![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998394198795.png?x-oss-process=style/stylename)
2.1.2 字数据大小
unsigned long、unsigned long int
都是同个意思
2.1.3 寻址和字节顺序
对于跨越多字节的程序对象,两个规则
- 这个对象的地址是什么
- 字内存中如何排序这些字节
地址为所使用字节最小的地址
排序方法有两个通用规则
- 大端法:最高有效字节中最前面的方法
- 小端法:最低有效字节中最前面的方法
2.1.4 表示字符串
字符串被编码为一个以null(值为0)字符结尾的字符数组,每个字符都由某个标准编码来表达,因此,文本数据比二进制数据具有更强的平台独立性
2.1.5 表达代码
不同机器类型使用不同的且不兼容的指令和编码方式,即使是完全一样的进程,运行中不同操作系统上也有不同的编码规则,因此二进制代码是不兼容的。
2.1.6 布尔代数
布尔代数符合分配率
a&(b|c) = (a&b)|(a&c)
a|(b&c) = (a|b)&(a|c)
布尔环
加分逆元(x+(-x) = 0)
a^a = 0
(a^b)^a = b
2.1.7 位级运算
掩码运算
掩码是一个位模式,表示一个字中选出的位的集合
例子
2.1.8 逻辑运算
||、&&和!分别代表媒体逻辑中的OR、AND和NOT运算
2.1.9移位运算
- 唯一例外是算术右移[10010101]的情况。因为操作数的最高位数1,填充的值就是1.
一般为算术右移
对于无符号数,右移必须是逻辑的
x>>j>>k等价于(x<<j)<<k
操作符的优先级中,加号的优先级比操作符的高
2.2 整数表示
编码整数的两种不同的方法:
- 只能表示非负数
- 能够表示负数,0,正数
下文用到的数学术语
2.2.1 整型数据类型
数据类型的典型取值范围
取值范围是不对称的——负数的范围比整数的范围大1
下表是C语言标准定义的每种数据类型必须能够表示的最小的取值范围。
无符号的编码
将位向量看作二进制表示的数,将获得了位向量的无符号表达
无符号数编码的定义
B2Uw是一个双射,函数B2Uw将每个长度为w的位向量都映射位0~2^w - 1之间的一个唯一值;反过来,U2Bw在0~2^w - 1之间的每一个整数都可以映射为一个唯一的长度为w的位模式。
2.2.3 补码编码
补码编码的定义
![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998595311062.png?x-oss-process=style/stylename)
字的最高有效位解释为负权,也叫做符号位。
符号位为1时值为负
符号位为0时值为非负
B2Tw也是双射
可表示的整数的范围
- 补码范围不对称:|TMin| = |TMax| + 1
之所以不对称是因为一半的位模式表示负数,而另一半表示为非负数,因为0是非负数所以比负数多1 - 最大的无符号值刚好比补码的最大值的两倍大一点:UMaxw = 2Tmxw + 1.
c语言标准并没有要求用补码形式来表示用符号整数,但是几乎所有的机器都是这么做的。
为来使代码具有最大可移植性,能够做所有可能的机器上运行,我们不应该假设任何可表示的数值类型,也不应该假设也符号数会使用何种特殊的表达方式。
许多程序的书写都是用补码来表示用符号数,并且具有图2-9和图2-10所示的典型的取值范围,这些程序能够值大量机器上移植
staint.h中定义了一组数据类型:intN_t和uintN_t(对不同N值指定N位用符号和无符号整数)
N:8、16、32和64
这些数据类型对应着一组宏,定义了每个N对值对应对最小和最大值:INTN_MIN、INTN_MAX和UINTN_MAX
有符号的其他表示方法(反码和原码)
2.2.4 有符号数和无符号数之间的转换
从位级角度思考
转换数值变但是位模式不变
补码转换为无符号数
- 原理
![公式2.5](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998611816561.png?x-oss-process=style/stylename) - 推导
![公式2.6](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998612864476.png?x-oss-process=style/stylename)
无符号数转换为补码
- 原理
- 推导
2.2.5 C语言中有符号数与无符号数
默认补码,要创建无符号常数,后缀加u/U
C语言运算中,如果一个运算数是有符号而另一个是无符号,C语言就会隐式将有符号强制转换为无符号数,并假设两个数都是非负的
![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16999196070225.png?x-oss-process=style/stylename)
2.2.6 扩展一个数的位表示
从较小类型转换到一个较大的类型(零扩展)
将无符号转换为另一个更大的数据类型
- 零扩展:在表示的开头添加0