前言
本章主要分为四部分,分别为:信息的储存、整数的表示
整数的运算、浮点数的表示
2.1 信息储存
2.1.1 十六进制表示法
2.1.2 字数据大小
字长
指明指针数据的标称大小
因为虚拟地址空间以这样的一个字来编码的,所以字长决定的最重要的
系统参数就是虚拟地址空间的大小。
2.1.3 寻址和字节顺序
大端法与小端法
点此学习
字节顺序成为问题的几种情况:
1.在不同机器之间通过网络传送二进制数据时
2.当阅读表示整数数据的字节序列
3.当编写规避正常的类型系统的程序时
2.1.4 表示字符串
c语言中字符串被编码为一个以 null (其值为 0 )字符结尾的字符数组。
文本数据比二进制数据有更强的平台独立性
2.1.5 表示代码
每一台机器的指令编码是不同的
2.1.6 布尔代数简介
计算
2.1.7 c语言中的位级计算
c语言支持按位布尔运算
位级运算的一个常见用法就是实现掩码计算。
2.1.8 c語言中的逻辑运算
|| && !
2.1.9 c语言中的移位运算
逻辑右移
算术右移:在左端补K个最高位有效位的值
对于无符号数,右移必须是逻辑的
2.2 整数表示
2.2.1 整型数据类型
我们可以看到 :
①、C 语言数据类型是可以用来指定大小,同时还可以指示表示的数是非负数(声明为 unsigned),或者负数(默认)。
②、数据类型分配的字节数会根据机器的字长和编译器有所不同,不同的大小所表示的范围是不同的。上图唯一一个与机器有关的取值范围是 long 类型的,64位机器使用8个字节(264),而32位机器使用4个字节(232)。
③、负数的范围要比正数的范围大1。这是为什么呢,请接着往下面看。
下面我们看一下 C 语言标准所定义的每种数据类型所能表示的最小的取值范围。
C 语言标准我们可以从上图得到:
①、正数和负数的取值范围是对称的。
②、int 数据类型可以用 2 个字节来实现。(216)
③、long 数据类型用4 个字节来实现。(232)
2.2.2 无符号数的编码
定义:假设对于一个w位的无符号整数,用二进制比特位可以表示为[xw-1 , xw-2 , … , x2 , x1 , x0]。那么我们可以用一个函数表示如下:
这个函数可以举几个简单的例子来看:
那么很显然,对于一个无符号编码的数,由 w 位的二进制序列构成,那么它的最小值,即所有位都为 0 ,用位向量表示即:【000…000】。
UMinw = 0
最大值即所有位都为 1,用位向量表示即:【111…111】
UMaxw = 1 * (1-2w) / 1 - 2 = 2w - 1
我们可以得出一个结论:无符号的二进制,对于任意一个w位的二进制序列,都存在唯一一个整数介于0 到 2w-1之间,与这个二进制序列对应。反过来,在0 到 2w-1之间的每一个整数,存在唯一的二进制序列与其对应。
2.2.3 补码编码
上面我们讲解了正整数的编码,那么在实际应用中,是存在负数的。而在计算机中,最常见的表示有符号的数就是补码。补码的定义如下:
其中最高有效位 xw-1 也称为符号位,符号位为 1 时表示负数,当设置为 0 时,表示非负数。下面我们看几个例子:
那么我们可以得出:当最高位为1,其余为全部是 0 的时候,即【1000…000】,表示补码格式的最小值:
TMinw = -2w-1
当最高位为 0,其余为全部是 1 时,即【0111…111】,表示补码格式的最大值:
TMaxw = 1 * (1 - 2w-1) / 1 - 2 = 2w-1-1
2.2.4 有符号数与无符号数之间的转换
强制类型转换的结果保持位值不变,只是改变了解释这些位的方式
如图所示,-12345 与 53191 位值相同
补码转换为无符号数
从补码到无符号数的转换,将负数转换为大的正数。
无符号数转换为补码(有符号数)
把大于有符号数最大值的数字转换为负值
2.2.5 c语言中的有符号数与无符号数
如果一个运算数是有符号数,另一个运算数是无符号数,那么c语言会隐式地将有符号数转换为无符号数。
2.2.6 扩展一个数字的位表示
2.2.7 截断数字
2.3 整数的运算
2.3.1 无符号加法
2.3.2 补码加法
2.3.3 补码的非
加法逆元
2.3.4 无符号乘法
2.3.5 补码乘法
2.3.6 乘以常数
2.3.7 除以 2 的幂
除以2的幂的无符号除法
补码除法
加入偏置量,修正不合理的舍入
2.4 浮点数
2.4.1 二进制小数
2.4.2 IEEE 浮点表示
因为高18位都为0 ,可以忽略,只看低14位
根据规格化数的表示规则,我们可以将12345用上图中的方式表示。又根据IEEE浮点数的表示规则,将小数点左边的1丢弃,由于单精度的小数字段长度为23,还需要在末端增加10个零,如下图所示,这就得到了浮点数的小数字段。
2.4.4 舍入