良心公众号
关注不迷路
菜鸡最近在读深入理解计算机系统(CS:APP)一书,将自己学习过程中的收获整理成笔记分享给大家。PS:本书是基于C语言展开论述的,但C语言的特性并不是本文的重点,书中的知识及设计思想对其他程序员同样适用。
自上周更新CS:APP第一章的相关内容之后,菜鸡收到了一些小伙伴的私信和评论的鼓励。菜鸡会再接再厉,持续分享。今天的主要内容是第二章——信息的表示和处理的相关知识总结。本章主要研究的是在计算机上如何表示数字和其他形式数据的基本属性,以及计算机对这些数据执行操作的属性。
书中在讲述整数的表示与计算时,采用了大量的数学语言的描述和推导证明,鉴于文章可读性的考虑,本文仅总结部分结论,对推导细节感兴趣的小伙伴,建议花时间认真研究一下书中的原理部分,逻辑相当严密,菜鸡在读的时候收获很大。
话不多说,开始!
现代计算机存储和处理的信息以二值信号表示。计算机的表示法是用有限数量的二进制数字(称为位(bit))来对一个数字编码。
三种最重要的数字表示:
无符号编码基于传统的二进制表示法,表示大于或者等于零的数字。
补码编码是表示有符号整数的最常见的方式,表示大于或者等于或者小于零的数字。
浮点数编码是表示实数的科学计数法的以2为基数的版本。
下表总结了整数表示和浮点数表示的特性对比:
数字表示 | 数值范围 | 是否精确 |
整数表示 | 相对较小 | 精确 |
浮点数表示 | 较大 | 近似 |
研究数字的实际表示是为了使编写的程序能在全部数值范围内正确工作,防止整数溢出、浮点数不可结合等错误,而且具有可以跨越不同机器、操作系统和编译器组合的可移植性。
C++与C语言使用完全相同的数字表示和运算,Java语言创造了一套新的数字表示和运算标准。C标准的设计允许多种实现方式,而Java标准在数据的格式和编码上是非常精确具体的。
信息存储:
大多数计算机使用8位的块(字节),作为最小的可寻址的内存单位。机器级程序将内存时为一个非常大的字节数组,称为虚拟内存。内存的每个字节都由一个唯一的数字来标识,称为它的地址,所有可能地址的集合称为虚拟地址空间。(一个虚拟地址空间只是一个展现给机器级程序的概念性映像,实际实现是将动态随机访问存储器(DRAM)、闪存、磁盘存储器、特殊硬件和操作系统软件结合起来,为程序提供一个看上去统一的字节数组)。
指针是C语言的一个重要特性。它提供了引用数据结构(包括数组)的元素的机制。与变量类似,指针也有两个方面:值和类型。它的值表示某个对象的位置,而它的类型表示那个位置上所存储对象的类型。
每台计算机都有一个字长,指明指针数据的标称大小。因为虚拟地址是以这样的一个字来编码的,所以字长决定的最重要的系统参数就是虚拟地址空间的最大大小。也就是说,对于一个字长为w位的机器而言,虚拟地址的范围为0 ~ 2^w - 1,程序最多访问2^w个字节。(举例:32位的机器,虚拟地址范围0 ~ 2 ^ 32 - 1)
排列表示一个对象的字节(以下简称字节序)有两个通用的规则:小端法(最低有效字节在最前面)和大端法(最高有效字节在最前面)。
需要关注字节序的几种情况:
当小端法(大端法)机器产生的数据被发送到大端法(小端法)机器时,接收程序会发现,字里的字节反序。为了避免这类问题,网络应用程序的代码编写必须遵守已建立的关于字节顺序的规则,以确保发送方机器将它的内部表示转换成网络标准,而接收方则将网络标准转换为它的内部表示。
当阅读表示整数数据的字节序列时,字节顺序也很重要。这通常发生在检查机器级程序时。
当编写规避正常的类型系统的程序时。在C语言中,可以通过使用强制类型转换或联合来允许以一种数据类型引用一个对象,而这种数据类型与创建这个对象时定义的数据类型不同。大多数应用编程都强烈不推荐这种编码技巧,但是它们对系统级编程来说非常有用,甚至是必需的。
C语言中字符串被编码为一个以null(其值为0)字符串结尾的字符串。每个字符都由某个标准编码来表示,最常见的是ASCII字符码。在使用ASCII码作为字符码的任何系统上都将得到相同的结果,与字节顺序和字大小规则无关。因而,文本类型比二进制数据具有更强的平台独立性。
整数表示:
C和C++都支持有符号(默认)和无符号数。Java只支持有符号数。
最常见的有符号数的计算机表示方式就是补码形式。将字的最高有效位解释为负权。有符号数还有其他两种标准的表示方法:反码和原码。这两种表示方法都有一个奇怪的属性,对于数字0有两种不同的编码方式(+0和-0)。几乎所有的现代机器都使用补码。
IEEE浮点表示:
IEEE浮点标准用V = (-1)^s * M * 2^E的形式来表示一个数:
符号(sign):s决定这数是负数(s = 1)还是正数(s = 0),而对于数值0的符号位解释作为特殊情况处理。
尾数(significand):M是一个二进制小数,它的范围是1 ~ 2 - ε,或者是 0 ~ 1 - ε。
阶码(exponent):E的作用是对浮点数加权,这个权重是2的E次幂(可能是负数)。
将浮点数的位表示划分为三个字段,分别对这些值进行编码:
一个单独的符号位s直接编码符号s。
k位的阶码字段编码阶码E。
n位小数字段编码尾数M,但是编码出来的值也依赖于阶码字段的值是否等于0。
本篇关于CS:APP——信息的表示和处理的知识点总结就到这里了。
欢迎大家一起讨论技术,共同成长!
学习 | 工作 | 分享
????长按关注“有理想的菜鸡”
只有你想不到,没有你学不到