二、信息的表示和表达

2.1 信息存储

2.1.1 十六进制表示法

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998390485614.png?x-oss-process=style/stylename)

转化为二进制需要从右到左每4分为一组转换(不足补0)

十进制和十六进制互选转换

十进制除16倒取余
![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998394198795.png?x-oss-process=style/stylename)

2.1.2 字数据大小

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998395609489.png?x-oss-process=style/stylename)

unsigned long、unsigned long int
都是同个意思

2.1.3 寻址和字节顺序

对于跨越多字节的程序对象,两个规则

  • 这个对象的地址是什么
  • 字内存中如何排序这些字节

地址为所使用字节最小的地址

排序方法有两个通用规则

2.1.4 表示字符串

字符串被编码为一个以null(值为0)字符结尾的字符数组,每个字符都由某个标准编码来表达,因此,文本数据比二进制数据具有更强的平台独立性

2.1.5 表达代码

不同机器类型使用不同的且不兼容的指令和编码方式,即使是完全一样的进程,运行中不同操作系统上也有不同的编码规则,因此二进制代码是不兼容的。

2.1.6 布尔代数

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998567614189.png?x-oss-process=style/stylename)

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998568366125.png?x-oss-process=style/stylename)

布尔代数符合分配率
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 位级运算

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998569179935.png?x-oss-process=style/stylename)

掩码运算

掩码是一个位模式,表示一个字中选出的位的集合

例子

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998575552748.png?x-oss-process=style/stylename)

2.1.8 逻辑运算

||、&&和!分别代表媒体逻辑中的OR、AND和NOT运算

2.1.9移位运算

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998578307265.png?x-oss-process=style/stylename)

  • 唯一例外是算术右移[10010101]的情况。因为操作数的最高位数1,填充的值就是1.

    一般为算术右移
    对于无符号数,右移必须是逻辑的
    x>>j>>k等价于(x<<j)<<k
    操作符的优先级中,加号的优先级比操作符的高

2.2 整数表示

编码整数的两种不同的方法:

  • 只能表示非负数
  • 能够表示负数,0,正数

下文用到的数学术语

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998582975352.png?x-oss-process=style/stylename)

2.2.1 整型数据类型

数据类型的典型取值范围

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998586485045.png?x-oss-process=style/stylename)

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998586665394.png?x-oss-process=style/stylename)

取值范围是不对称的——负数的范围比整数的范围大1

下表是C语言标准定义的每种数据类型必须能够表示的最小的取值范围。

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998588029453.png?x-oss-process=style/stylename)

无符号的编码

将位向量看作二进制表示的数,将获得了位向量的无符号表达

无符号数编码的定义

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998590944911.png?x-oss-process=style/stylename)

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998591542514.png?x-oss-process=style/stylename)

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998592255921.png?x-oss-process=style/stylename)

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时值为非负

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998597654820.png?x-oss-process=style/stylename)

B2Tw也是双射

可表示的整数的范围

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998599315139.png?x-oss-process=style/stylename)

  • 补码范围不对称:|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

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998607174352.png?x-oss-process=style/stylename)

有符号的其他表示方法(反码和原码)

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998607836002.png?x-oss-process=style/stylename)

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998608162844.png?x-oss-process=style/stylename)

![图2-15](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998608493945.png?x-oss-process=style/stylename)

2.2.4 有符号数和无符号数之间的转换

从位级角度思考
转换数值变但是位模式不变

补码转换为无符号数

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998613857100.png?x-oss-process=style/stylename)

无符号数转换为补码

  • 原理

![公式2.7](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16998613713711.png?x-oss-process=style/stylename)

  • 推导

![公式2.8](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16999191653704.png?x-oss-process=style/stylename)

![图2-17](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16999191775362.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)

![](http://mwebpng.oss-cn-beijing.aliyuncs.com/2023/12/15/16999196160028.png?x-oss-process=style/stylename)

2.2.6 扩展一个数的位表示

从较小类型转换到一个较大的类型(零扩展)

将无符号转换为另一个更大的数据类型

  • 零扩展:在表示的开头添加0