这里写自定义目录标题

  • 第二章 信息的表示和处理
    • 2.1 信息存储
      • 2.1.1 十六进制表示法
      • 2.1.2 字数据大小
      • 2.1.3 寻址和字节顺序
      • 2.1.4 表示字符串
      • 2.1.5 代码表示
      • 2.1.6 布尔代数简介
      • 2.1.7 C语言中的位级运算
      • 2.1.8 C语言中的逻辑运算
      • 2.1.9 C语言中的位移运算
    • 2.2 整数表示
      • 2.2.1 整型数据类型
      • 2.2.2 无符号数的编码
      • 2.2.3 补码编码
      • 2.2.4 有符号数和无符号数之间的转换
      • 2.2.5 C语言中的有符号数与无符号数
      • 2.2.6 扩展一个数字的位表示
      • 2.2.7 截断数字
      • 2.2.8 关于有符号与无符号的建议
    • 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.3.8 关于整数运算的最后思考
    • 2.4 浮点数
      • 2.4.1 二进制小数
      • 2.4.2 IEEE浮点表示
      • 2.4.3 数字示例
      • 2.4.4 舍入
      • 2.4.5 浮点运算
      • 2.4.6 C语言中的浮点数
    • 2.5 小结

第二章 信息的表示和处理

2.1 信息存储

  • 大多数计算机使用8位的块(称为字节(byte)),作为最小的可寻址的内存单位,而不是去访问单独的一个位。
  • 机器级程序将计算机的内存看做是一个很大的字节数组,称作虚拟内存。虚拟内存的每个字节都由唯一的数字来标识,称它为地址

2.1.1 十六进制表示法

  • 一个字节有8位,即用二进制表示会有八位数,这样表示会比较冗长,所以使用最多的还是十六进制数(如0xA9),一个位十六进制数就可以表示一个8位的二进制数。同理,一个字节可以由两个十六进制数表示。
  • 十进制,二进制,十六进制转换图

2.1.2 字数据大小

  • 每台计算机都有字长(32位或64位,这里的概念注意跟字节区分),指明指针数据的标称大小。
  • 因为虚拟地址是一个字长来表示的,所以字长的大小决定了虚拟地址的寻址大小。
  • 在编译的时候就会决定一个程序是32位程序还是64位程序
  • C语言中的char型就表示一个单独的字节,尽管它是用来保存单个字符而得名。

2.1.3 寻址和字节顺序

  • 在几乎所有的机器上,多字节对象都被存储为连续的字节序列,对象的地址就是字节序列中最小的地址。
  • 最低有效字节在最前面的方式称为 小端法(little endian)
  • 最高有效字节在最前面的方式成为 大端法(big endian)
  • Android 和 IOS都是只能运行小端法
  • 尤其注意的是不同类型的机器通过网络传输二进制数据的时候,会发现字节序列是反序的
  • 阅读整数数据的字节序列时,字节的顺序也很重要。
  • 在编程中,取对象的字节表示时,字节顺序也很重要。

2.1.4 表示字符串

  • C语言中字符串被编码以一个以null(其值为0)字符结尾的字符数组
  • 字符串中的每个字符都是以某个标准编码来表示,最常见的就是ASCII码。(可以使用命令man ascii 来生成一张ASCII字符编码表)

2.1.5 代码表示

  • 代码在不同机器上编译成机器指令时,字节码的表示是完全不同的。
  • 从计算机的角度来看,一个程序仅仅是一个字节序列。除了可能用来帮助调试的表以外,机器没有关于原始源程序的任何信息。

2.1.6 布尔代数简介

  • 逻辑值(真)和逻辑值(假)分别对应二进制编码1和0
  • 布尔代数运算:

2.1.7 C语言中的位级运算

  • C语言的一个很有用的特性就是它支持按位布尔运算,这种运算可以运用于任何“整型”的数据类型上。
    例如:
  • 位级运算最常见的用法就是实现掩码运算

2.1.8 C语言中的逻辑运算

  • C语言还提供逻辑运算或(||)、与(&&)、非(!),逻辑运算容易跟位运算混淆,它们是完全不同的两个概念。
  • 逻辑运算中,将所有非零的参数都表示TRUE,参数0表示为FASLE,它们返回1或者0,分别表示结果为TRUE或FALSE,例如:

2.1.9 C语言中的位移运算

  • 位移运算是一种按位操作的模式,比如左移(即 x<<k, x变量向左移动k位),就是将x的最高k位舍弃,并在低位补k个0。
  • 右移比较特殊(x>>k),分为两种情形:算术右移和逻辑右移。
  • 逻辑右移:在左端补k个0。
  • 算术右移:在左端补k个最高有效位。
  • C语言中并没有明确表示对有符号的右移使用哪种右移,但是对于几乎所有的编译器来说,对有符号使用算术右移,对于无符号来说右移都是逻辑右移。
  • 与C语言相比,JAVA语言就明确指定了算术右移(x>>k)或逻辑右移(x>>>k)。

2.2 整数表示

  • 整数表示分为两种:一种是非负数表示,即0和正数的表示。
  • 另一种是能表示负数、零和正数

2.2.1 整型数据类型

  • C语言支持多种类型的整型数据类型 – 表示有限范围的整数
    -
  • 32位和64位程序上取值范围不同的就是long整型。
  • 值得注意的是有符号的数据类型,取值不是对称的,负数范围取值比正数取值范围大1。(与负数的编码有关)
  • C语言和C++语言都支持有符号(默认的)和无符号, JAVA只支持有符号数

2.2.2 无符号数的编码

  • 无符号数编码定义:

    其中 B2UwB2U_wB2Uw​ 表示将一个www位的二进制向量x⃗\vec{x}x(其中的元素都是二进制数)为无符号数的函数(Binary To Unsigned 的缩写 )
  • 从上面的定义可以看出,这种编码的最大值,就是www位二进制全为1的情况,最小值就是全为0的情况。
  • 每一个0 ~ 2w−12^w-12w−1范围内的整数都可以映射为一个唯一的www位的二进制数,反之 每个www位的二进制数都可以映射为0 ~ 2w−12^w-12w−1范围内的整数(函数的这种属性称之为双射)

2.2.3 补码编码

  • 计算机表示负数的形式是通过补码(two’s-complement)形式来表示。
  • 补码就是将最高有效位解释为负权(negative weight)。
  • 补码编码的定义:
  • 最高位为负权,从公式可以看出,当最高位二进制数为1时,此时表示的是负数,最高位也称为符号位。
  • 补码表示的最小值是最高位为1,其他位为零的情况。
  • 补码表示的最大值是最高位为0,其他位都为1的情况(从这里就可以看到有符号类型的表示范围不是对称的原因,一半的范围用来表示非负数,另一半用来表示了负数)。
  • 补码的表示也是一一对应的关系,即一个二进制数可以唯一的转换为一个整数,反之也是唯一对应的。
  • 无符号的最大值刚好比有符号的最大值的两倍大一: Umaxw=2Tmaxw+1Umax_w = 2Tmax_w + 1Umaxw​=2Tmaxw​+1
  • 在java中单字节数据类型称为byte,而不是char。

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

  • 对于机器来说,有符号数和无符号数之间的转换是不会改变一个数的位级表示,只是改变了解释这些位的方式。
  • 对于同样字长的有符号数和无符号数之间相互转换的规则就是:位模式不会变,但是它表示的数值可能会改变(比如有符号的最高位是符号位,转换为无符号时,它就是一个有权值的位。)
  • 补码转换为无符号数:
  • 所以直观的从公式看,一个有符号数负数转换为无符号时,会成为一个很大的正数。(也可以解释为,因为负数的最高位为1,转换为无符号数时,位模式不会变,最高位还为1,这时解释成无符号数时就会变成很大的正数)。
  • 非负数的有符号数转换为无符号数时,会保持不变。
  • 无符号数转换为补码
  • 所以可以总结一下,当一个数的位模式最高位为0时,无符号数和有符号数(补码)之间转换,数值不会改变,如果最高位为1时,那么在表示无符号数时,最高位就是实实在在的权值,而表示有符号时,最高位就是符号位,表示负数。

2.2.5 C语言中的有符号数与无符号数

  • C语言支持无符号与有符号,默认状态下C语言声明的整数都是有符号数,如果要声明无符号数需要在数字后面加U或u 或者是用关键字unsigned声明。
  • C语言中的有符号数都是用补码表示
  • 无符号与有符号之间的转换,主要遵守的原则就是底层的位表示不会变。
  • 由于C语言中是同时包含无符号与有符号数,当执行一个运算就需要尤其注意,**当一个运算数是无符号,另外一个是有符号数时,C语言会隐式的将有符号数转换为无符号数,并且都将他们看作非负数处理。**特别是在做大小判断的时候尤其需要注意。

2.2.6 扩展一个数字的位表示

  • 将一个无符号数扩展成为一个更大的无符号数,我们就在最高位添0,这种称为零扩展(zero extension),原理如下,该原理遵守了无符号数的定义。
  • 将一个有符号扩展成为一个更大的有符号数,可以执行符号位扩展(sign extension),即在扩展时添加最高有效位的值:

2.2.7 截断数字

  • 无符号数截断

    即 截断时直接去掉高位多余的位,剩下的位表示继续使用

  • 补码截断

    从公式中的原理来看,与无符号类似,截去高位多余的位表示,不同的是,剩下的位模式的最高位将变成符号位

2.2.8 关于有符号与无符号的建议

  • C语言中有很多地方都碰到运算符,尤其是从有符号到无符号的隐式转化,会导致错误或漏洞的方式。避免这一类的问题就是绝不使用无符号数事实上,除了C语言很少有语言支持无符号整数
  • 当我们把一个变量仅仅看作是位的集合而不表示任何数字意义的时候,这个时候使用无符号数就是非常有用的。

2.3 整数运算

2.3.1 无符号加法

  • 无符号加法只用关注溢出的情况,当两个无符号相加溢出时,有且只会溢出一位。所以两个无符号加法定义如下:

  • 说一个运算结果溢出,是指运算之后的结果,不能用指定的数据类型的字长来表示。

  • 检测一个加法溢出:

  • 无符号数求反

    每一个无符号数,都可以找到一个与之相加最后结果等于零的数(溢出之后,刚好结果为零)

2.3.2 补码加法

  • 对于补码加法,即是有符号数加法,我们就必须要确定几种情况,结果太大?或者结果太小?
  • 两个无符号数之和和两个有符号数之和有相同的位级表示,大多数机器使用同样的指令来执行无符号或有符号加法。
  • 检测补码加法中的溢出

2.3.3 补码的非

  • 补码的非
  • 当一个补码是最小值的时候,它的非就是它自己的加法的逆(加法的逆是指这个数加上这个逆等于零)。
  • 根据定义,补码的最小值就时符号位(即最高位)为1,其它位为0的情况,它加上它本身刚好产生溢出,成为0,所以TMinwTMin_wTMinw​的逆就他本身。

2.3.4 无符号乘法

  • 将一个无符号数截断为w位等价于计算该值模2w2^w2w

2.3.5 补码乘法

  • 对于无符号和有符号来说,乘法的位级表示都是一样的。

2.3.6 乘以常数

  • 在大多数情况下, 乘法的运算需要十个或者更多的机器周期,然而其他整数运算只需要一个时钟周期。

  • 原理:乘以2的幂

  • 原理:与2的幂相乘的无符号乘法

  • 原理: 与2的幂相乘的补码乘法

  • 无论是补码或者无符号运算,与2相乘的幂都可能溢出,即使是溢出,通过移位获得的结果也是一样的

  • 由于整数乘法比位移和加法的运算代价都要大的多,很多C编译器试图以位移、加法和减法的组合来优化乘法运算带来的运算代价

2.3.7 除以2的幂

  • 整数除法比乘法更慢 – 需要30个或更多时钟周期,所以除以2的幂也可以通过位移运算来实现,与乘法不同的是除法是右移,无符号和补码数分别使用逻辑位移和算术位移来达到目的

  • 整数的除法总是舍入到零(可以理解为做舍入操作时,总是向零的方向做舍入)

  • 除以2的幂的无符号除法:就是逻辑右移:

  • 因为我们想要达到的效果是舍入到零,那么做2的幂的补码除法如下:

2.3.8 关于整数运算的最后思考

  • 整数运算在计算机中实际上是一种模运算形式,表示整数的位有限导致运算结果可能溢出。
  • 在底层的运算中,无论运算数是无符号或是补码,它们都有非常类似或完全一样的位级行为。

2.4 浮点数

  • 早在浮点数诞生之前,有很多编码浮点数的标准,随着时间的推移,目前计算机中的浮点数都支持IEEE的浮点标准。这大大提高了程序在不同机器上的可移植性。

2.4.1 二进制小数

  • 表示方法:
  • 浮点数只能很精确的表示可以写成形如x∗2yx*2^yx∗2y的数,其它的数只能用很近似的值表示,浮点数二进制表示位数越多,表示的小数精度越高。

2.4.2 IEEE浮点表示

  • IEEE浮点数表示法:
  • IEEE浮点数的二进制表示:
  • 浮点数表示根据阶码的值可以把编码分成以下三种情况:
    • 规格化的: 阶码不全为零且不全为1,在这种情况下,阶码字段解释为以偏置形式表示的有符号整数,其值为E=e-bias, 其中e的位表示为ek−1ek−2....e0e_{k-1}e_{k-2}....e_{0}ek−1​ek−2​....e0​,bias是一个等于2k−1−12^{k-1}-12k−1−1的偏置值。小数字段二进制表示0.fn−1.fn−2.fn−3.......f00.f_{n-1}.f_{n-2}.f_{n-3}...... .f_{0}0.fn−1​.fn−2​.fn−3​.......f0​,尾数M定义为M=1+fM=1+fM=1+f,这种方式叫做隐含的以1开头的表示。
    • 非规格化的: 阶码全为零:当阶域为全零时,表示的非规格化形式,阶码值是E=1−BiasE=1-BiasE=1−Bias,而尾数的值是M=fM=fM=f,也就是小数字段的值,不包含隐含的开头的1。非规格化一般有两种用途,一种是表示数值零,另一种是表示非常接近0.0的数值,它提供了一种属性称为逐渐溢出属性,可以使能表示的数字均匀分布接近0.0。
    • 无穷大:阶码全为1,且尾码全为零。 当指阶全为1的时候出现,当小数域全为零,表示无穷大,当符号位s为0时,表示无穷大,当符号位s为1时,表示无穷小。
    • NaN:阶码全为1,且尾码不等于零。当小数位不全为零时,表示NaN(即not a number的缩写。),在一些程序中,表示一些没有初始化的数据是很有帮助的。

2.4.3 数字示例

  • 下图展示了一组数值,假定可以用6位来表示浮点数,其中k=3的阶码位和n=2的尾数位:

    可以看到,浮点数可表示的数并不是均匀分布的,越靠近原点处它们越稠密
  • 再看一个示例:假定一个8位浮点格式示例,其中k=4的阶码,和n=3的小数位(还有一个留给是符号位),偏置量为24−1−1=72^{4-1}-1=724−1−1=7:

    可以观察到最大非规格化数和最小规格化数之前的平滑转变。这种平滑转变就要归功于对非规格化数的EEE的定义(我们定义为1−E1-E1−E)。

2.4.4 舍入

  • 因为表示浮点的方法限制了浮点表示的范围和精度,所以浮点数只能近似的表示实数运算。
  • IEEE浮点格式定义了四种不同的舍入方式:向偶数舍入,向零舍入,向下舍入,向上舍入:
    • 向偶数舍入:也称为向最接近的值舍入,但是当值处于中间的请求,那么他会向舍入结果最低有效位是偶数的方向舍入,所以举例来说1.5或者2.5,通过向偶数舍入的结果都是2。而1.4的舍入结果就是1。
  • 向偶数舍入一般会是用在避免统计偏差的情况,如果总是使用向上舍入或者向下舍入,在统计数据时数据的误差就会因为舍入的原因,不断加大(数据越多,误差就会越大),向偶数舍入在大多数情况下可以避免这种情况,50%的时间它是向上舍入,50%的时间是向下舍入。

2.4.5 浮点运算

  • 把浮点数看作实数,实数做运算后,对结果进行舍入,得到的最后的值就时浮点数做运算的结果。
  • 浮点数运算不具有结合性,因为浮点数的运算可能有舍入操作,每一步运算的舍入都可能不一样

2.4.6 C语言中的浮点数

  • C语言版本提供了两种不同类型的浮点数:float 和 double , 分别是单精度和双精度。
  • C语言不要求使用IEEE浮点,所以就没有标准的方法来改变舍入方式或者得到诸如-0,负无穷大,或正无穷大。
  • C 语言中,int 、float 、double之间的转换,需要注意以下几点:

2.5 小结

  • C语言将信息编码为bits(比特),通常组织成为字节序列,一个字节8位,有不同的编码方式用来表示整数,实数或字符串。
  • C语言对有符号使用补码表示,对小数使用浮点数表示。深刻的理解他们的位级编码方式,对正确编程特别是正确的数值运算有很大帮助。
  • 浮点数由于他很特别的编码方式,运算的结合律对于浮点数来说都是不适用的,这一点尤为需要注意。

深入理解计算机系统读书笔记(第二章 信息的表示和处理)相关推荐

  1. 计算机系统导论——读书笔记——第二章 信息的表示和处理(持续更新)

    第二章 信息的表示和处理 2.1 信息存储 2.1.1 十六进制 2.1.2 字数据大小 2.1.3 寻址和字节顺序 1.地址:对象所使用的字节中最小的地址 2.大端法:最高有效字节在前 小端法:最低 ...

  2. 《深入理解计算机系统》(CSAPP)读书笔记 —— 第二章 信息的表示和处理

    本章主要研究了计算机中无符号数,补码,浮点数的编码方式,通过研究数字的实际编码方式,我们能够了解计算机中不同类型的数据可表示的值的范围,不同算术运算的属性,可以知道计算机是如何处理数据溢出的.了解计算 ...

  3. 《计算传播学导论》读书笔记——第二章文本分析简介

    <计算传播学导论>读书笔记--第二章文本分析简介 第一节 文本分析研究现状 常用文本挖掘技术 第二节 文本分析与传播学研究 (一)为什么文本挖掘技术逐渐受到传播学者的关注 (二)不同文本分 ...

  4. 《深入理解计算机系统》第2章 信息的表示与处理

    <深入理解计算机系统>第2章 信息的表示与处理 允许任何人转载,仅作为学习交流. 萌新一枚,本着交流学习经验的心态,写了这篇文章.若文章有误,还请各位大佬指正,谢谢(๑•̀ㅂ•́) ✧ 2 ...

  5. 《软件测试经验与教训》读书笔记---第二章

    <软件测试经验与教训>读书笔记--目录 第一章 测试员的角色 第二章 按测试员的方式思考 第三章 测试手段 第四章 程序错误分析 第五章 测试自动化 第六章 测试文档 第七章 与程序员交互 ...

  6. 计算机网络(第五版 作者:AndrewS.Tanenbaum David J.Wetherall 清华大学出版社)读书笔记----第二章的学习

    计算机网络第二章--物理层读书笔记 1.物理层是网络的技术设置,物理层的材质和带宽决定了最大的传输速率. 2.传输介质的分类:引导性(有线介质)和非引导性(无线介质). (1)有线介质:磁介质.双绞线 ...

  7. C++ Primer Plus读书笔记第二章

    自学了一段时间的C++打算还是要系统的整理一下一些知识点,让学习思路更清晰,不然老是学一点忘一点,这个读书笔记用来记录这段时间对C++ Primer Plus一书中知识点的记录,尽量会写的详细一点.直 ...

  8. 【编程珠玑】读书笔记 第二章 算法

    2013-07-11 22:00:28 第二章 算法 本章围绕三个问题进行算法讨论,包括元素的查找.字符串的旋转.以及变位词的查找. 下面给出了实现代码.以及测试结果. 问题一 查找不存在的元素 思路 ...

  9. 《辛雷学习方法》读书笔记——第二章 心态

    第二章 心态   (1)保持良好心态:学习时保持良好心态,你才能比较容易入门.深入掌握知识.灵活运用知识.学习时始终保持着轻松愉悦振奋的心情,你就容易产生学习心得,更容易灵活运用. (2)爱情对心态影 ...

最新文章

  1. 2019年上半年收集到的人工智能Python编程干货文章
  2. 打开了Visual Studio,又关了
  3. Linux Shell 命令--cut
  4. MACIOS Socket编程
  5. 在python中类型属于对象变量是没有类型的_如何理解python对象有类型,变量无类型...
  6. c语言用链表实现成绩管理系统,C语言写的学生成绩管理系统(链表)
  7. Azkaban时区问题导致调度差1天
  8. 推荐——《梦想金山》
  9. Gap Statistic 间隔统计量
  10. matlab实现将彩色图像转换成灰色图像的方法
  11. 苹果自带的清理软件_苹果清理软件哪个好,哪个更适合自己 - 単子
  12. 日志追踪-类加载器-自定义类加载器
  13. python快速处理excel表格-python 处理 Excel 表格
  14. BootStrap表格鼠标悬停颜色修改
  15. PD 协议初理解(转)
  16. 怎样在手机设置无线网络连接服务器,如何用手机设置wifi路由器?
  17. 仿微信做个极速二维码扫描功能
  18. predict函数在回归分析中的应用
  19. Java Spring中同时访问多种不同数据库
  20. oracle连接打印机,使用 CUPS 命令设置网络打印机

热门文章

  1. C++小游戏(原创)——2048
  2. 魅族账号服务器返回异常,替魅族捏把汗 Flyme同步业务异常 部分用户同步数据错乱...
  3. C#.NET自动生成Excel图形报表
  4. 简报 | 乌克兰议会拟为加密公司提供税收优惠,加密行业将成为本国的新经济引擎?
  5. C++ web httpserver
  6. php flot,php-使用mysql和ajax用FLOT绘制图形
  7. Qt:ini文件注释语法
  8. 程序员求婚代码html,火热的程序员表白方式,调皮弹窗表白代码,赶紧拿去试试吧...
  9. 安卓手机管理器_一款多功能的手机文件/程序/进程管理器
  10. matlab字母上横线,为什么运行后是一条横线啊???