首页 > 其他分享 >计组笔记第二章——数据的表示和运算

计组笔记第二章——数据的表示和运算

时间:2024-07-16 16:30:56浏览次数:20  
标签:计组 符号 尾数 补码 笔记 times 第二章 原码 运算

本章问题:

  • 数据如何在计算机中表示?
  • 运算器如何实现数据的算术、逻辑运算?

2.1.1 进位计数制

十进制计数法

  • 古印度人发明阿拉伯数字。
  • 基于乘法思想。
  • 十进制表示方式:
    整数情况下:

\[K_nK_{n-1}...K_2K_1K_0 = K_n \times 10^n + K_{n-1} \times 10^{n-1} + ... + K_2 \times 10^2 + K_1 \times 10^1 + K_0 \times 10^0 \]

带小数的情况:

\[K_nK_{n-1}...K_2K_1K_0K_{-1}K_{-2}...K_{-m} = K_n \times 10^n + K_{n-1} \times 10^{n-1} + ... + K_2 \times 10^2 + K_1 \times 10^1 + K_0 \times 10^0 + K_{-1} \times 10^{-1} K_{-2} \times 10^{-2} + ... + K_{-m} \times 10^{-m} \]

  • 上面的公式中\(10^n\)被称为位权。

推广:r进制计数法

  • r进制转十进制公式:

\[K_nK_{n-1}...K_2K_1K_0K_{-1}K_{-2}...K_{-m} = K_n \times r^n + K_{n-1} \times r^{n-1} + ... + K_2 \times r^2 + K_1 \times r^1 + K_0 \times r^0 + K_{-1} \times r^{-1} K_{-2} \times r^{-2} + ... + K_{-m} \times r^{-m} \]

  • 基数:每个数码位所用到的不同符号的个数,r进制的基数为r。
  • 计算机中常用进制:
    • 二进制:0,1
    • 八进制:0,1,2,3,4,5,6,7
    • 十进制:0,1,2,3,4,5,6,7,8,9
    • 十六进制:0,1,2,3,4,5,6,7,8,9,A, B, C, D, E, F
  • 二进制适合计算机的原因:
    • 可使用两个稳定状态的物理器件表示。
    • 0,1正好对应逻辑值假、真。方便实现逻辑运算。
    • 可以很方便的使用逻辑门电路实现算术运算。

各种进制的常见书写方式

  • 二进制:
    \((1010000101010)_2 = 010000101010B\)
  • 八进制:
    \((1652)_8\)
  • 十六进制:
    \((165A)_{16} = 165AH = 0x165A\)
  • 十进制:
    \((160)_{10} = 160D\)

十进制转其他进制

例如:十进制75.3转r进制:

  • 整数部分(除基取余法):
    \(\frac {75}{r} = 商(X)…余数(K_0)\)
    \(\frac {X}{r} = 商(X)…余数(K_1)\)
    ……
    \(\frac {X}{r} = 商(0)…余数(K_n)\)
    r进制整数部分为:
    \(K_nK_{n-1}...K_2K_1K_0\)
  • 小数部分(乘积取整发):
    \(0.3 \times r = 整数(K_{-1}) + 小数(X)\)
    \(X \times r = 整数(K_{-2}) + 小数(X)\)
    ……
    r进制小数部分为:
    \(K_{-1}K_{-2}...\)
  • 注:十进制的小数部分可能无法用其他进制的有限小数精确表示,可能出现循环。
  • 如果熟悉二进制的每位对应的十进制数,在求十进制转八、十六进制时可以先十进制转二进制,然后二进制转八、十六进制。

真值和机器数

  • 如果数字带符号,存储时需要一位符号位。
  • 真值:符合人类习惯的数字。
  • 机器数:数字实际存到机器里的形式,它的正负号需要被“数字化”。

2.1.2 BCD码

  • BCD(Binary-Coded Decimal): 使用二进制编码的十进制。
  • 二进制方便机器处理,十进制符合人类习惯,但是用二进制转十进制的公式转换的过程较为复杂,所以引出BCD编码。BCD码的思路是用4b二进制表示1为十进制。4b二进制可以表示16个数,对应十进制有6个数的冗余,但是转换起来比较方便。

8421码(重点)

  • 8421码的4位二进制对应十进制分别位8421,也就是一般状况下二进制和十进制的对应关系。
  • 下表给出8421码和十进制的映射关系:
十进制数 8421码
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
  • 例:985用9421码表示为:1001 1000 0101
  • 8421码如何进行加法运算?
    • 投机取巧法: 先用十进制加出结果,然后把结果用8421码表示。
    • 计算机方法:
      例如十进制5 + 8,对应二进制8421码为0101 + 1000 = 1101. 但是1101不在8421码的映射表里。计算机的处理方式为当计算结果出现超出映射表的数,就给这些数加六(0110)(因为8421码有6位冗余),这样这个数就会向高位进一,剩下的部分就是低位的结果。例如1101 + 0110 = 1 0011,对应8421码的13.
    • 例: 9 + 9的9421码运算过程:
      解:1001 + 1001 = 10010
      10010超出映射表,修正为10010 + 0110 = 11000 = 18

余3码

  • 映射规则: \(8421码 + (0011)_2\)
  • 十进制映射表如下:
十进制数 余3码
0 0011
1 0100
2 0101
3 0110
4 0111
5 1000
6 1001
7 1010
8 1011
9 1100
  • 8421码每位的权值是固定的,称为有权码,而余3码每位权值不固定,称为无权码。

2421码

  • 每位权值分别为2421.
  • 十进制映射表如下:
十进制数 2421码
0 0000
1 0001
2 0010
3 0011
4 0100
5 1011
6 1100
7 1101
8 1110
9 1111
  • 2421码的04首位都是0,59首位都是1,这样可以使2421码编码策略唯一。

2.1.3 无符号整数的表示和运算

  • 无符号整数,即自然数:0,1,2,3,4……
  • C语言中的无符号整数:
unsigned short a = 1; //无符号整数(短整型,2B)
unsigned int b = 2; //无符号整数(整型,4B) 

无符号整数在计算机硬件内如何表示?

  • 计算机硬件能支持的无符号整数位数有上限,现在个人计算机机器字长通常是64位,或至少为32位。
    本节以8位机器字长为例:
  • 下图为计算机存储无符号数的示意图:
    计算机存储无符号数的示意图
    由图可知,如果要把一个超出机器字长表示范围的数强行塞进一个机器字长内,计算机只保留低8位,其余高位部分溢出。
  • 全部二进制都是数值为,没有符号位。
  • n bit无符号整数的表示范围位\(0\)~\(2^{n-1}\),超出范围就会溢出。
  • 可以表示的最小的数全是0,最大的数全是1.

无符号整数的加减法运算如何用硬件实现?

  • 无符号整数加法:从最低位开始,按位相加,并往最高位进位。
    例:99 + 9
    解:01100011 + 00001001 = 01101100

  • 无符号整数减法:
    人类方法:从最低位开始,按位相减,不够减的话从高位借位。
    计算机方法:

    • “被减数”不变,减数全部按位取反,末位+1,减法变加法。
    • 从最低位开始,按位相加,并往最高位进位。
    • 原因是加法电路造假便宜,减法电路更贵。
      例:99 - 9
      解:01100011 - 00001001
      = 01100011 + (11110110 + 1)
      = 01100011 + 11110111
      = 1 01011010
      最高位的1溢出,最终结果为01011010

2.1.4 带符号整数的表示和运算

原码

  • 最高位表示正负号,其余位表示数值位。
  • 原码表示图如下:
    原码表示
    符号位0/1对应正/负,剩余数值位表示真值的绝对值。
  • 若机器字长为n-1位,带符号整数的原码表示范围:\(-(2^n - 1) \leq x \leq 2^n-1\)
  • 真值0的原码表示方式有两种,一种是+0,一种是-0.
  • 常见书写方法:\([-19]_原 = 1,0010011\),符号位和数值位中间可以用逗号隔开。如果题目没说机器字长,可以省略数值位开头的0.
  • 原码缺点:符号位不能参与运算。

补码、反码

  • 原码到反码补码的转换:
    原码到反码补码的转换
  • 正数原、反、补码相同。
  • 复数原码到反码符号位不变,数值位按位取反,反码到补码末位加一。
  • 原、反、补的最高位都反应正负。
  • 原->反和反->原都是符号位不变,数值位按位取反。反码到补码末位加一,补->反末位减一。
  • 原<->补的快速转换:
    正数不变,负数从右往左找到第一个1,这个1左边的所有数值位按位取反,原->补和补->原都一样。
  • 补码的加减运算:
    • 补码的加法运算:
      +19 + (-19) = 00010011 + 11101101 = 1,00000000
      最前面的1溢出不考虑,最终结果为0.
    • 补码的减法运算:
      因为加法电路比减法电路便宜,所以尽量把减法运算变成等价的加法运算。
      \([A]_补 - [B]_补 = [A]_补 + [-B]_补\)
      \([B]_补\)<->\([-B]_补\)全部位按位取反、末位+1. 也可以从右往左找到第一个1,这个1左边所有位(包括符号位)都取反。
      无符号整数的减法也是被减数不变,减数全部位按位取反,末位+1,减法变加法。
      也就是同一套电路可以实现无符号和有符号整数的减法。

各种码的基本特性总结:

各种码的基本特性总结

  • 注:是否溢出的计算可以手算带十进制验证。

移码

  • 原、反、补、移码的转换:
    原、反、补、移码的转换
  • 补码的基础上符号位取反可得移码。
  • 移码的正数表示和其他三个码不同。
  • 移码只用于表示整数。原、反、补码也可以表示小数。
  • 移码整数的表示范围和补码相同,机器字长为n+1位时,表示范围都是:
    \(-2^n \leq x \leq 2^n-1\)
  • 移码补码对应图:
    移码补码
    在-128~127之内,移码的真值从小到大增加。

2.1.5 定点小数

  • 定点含义:小数点的位置固定。带符号整数也可以叫定点整数,默认小数点固定在最后一位之后。
  • 定点小数的小数点位置默认在符号位之后。

原码

定点小数的原码表示

  • 定点整数的符号位与数值位通常用逗号隔开,定点小数的符号位和数值位通常用“.”隔开。

反码、补码

  • 和定点整数的转换方式相同:
    正数不变。
    负数:
    原<->反:符号位不变,数值位按位取反;
    原<->补:从右往左找第一个1,这个1左边的所有数值位按位取反。
    反->补:负数末位+1.

定点小数的加减运算

运算规则:
定点小数的加减运算
和定点整数的加减运算规则相同。

定点小数和定点整数的总结:

  • 定点小数的默认小数点在符号位之后,定点整数默认小数点在数值位之后。
  • 定点小数和定点整数对照表如下:
    定点小数和定点整数对照表
  • 定点小数和定点整数在位数扩展时,拓展位置不一样。
    定点小数位数扩展是在数值位末位加0.
    定点整数位数扩展是在符号位后面加0.

2.2.0 奇偶校验码(大纲已删)

校验原理

如果PCA和PCB要传输4钟信号ABCD,那么理论上只需要2b的数据来表示这4个合法状态。如下表所示

信息 A B C D
编码 00 01 10 11

但是在数据传输过程中,可能会出现位错误,所以可以采用校验的方式,用3b来编码这4个合法状态(会有4中冗余的非法状态),编码方式如下表:

信息 A B C D
编码 100 001 010 111
表中的4中编码为合法状态,另外4中为冗余非法状态。

奇偶校验

  • 奇偶校验码:
    奇偶校验码
  • 检验错误的方式:
    一串带着校验码的数据传输过去,约定好是奇校验或者偶校验,接收方先检查1的奇偶性,如果传输过程中发生奇数bit的数据错误,则接收方可以测出来,但是发生偶数bit的数据错误,接收方就检查不出来了。
  • 偶校验的硬件实现:各信息进行异或(模2加)运算,得到的结果极为偶校验位。

2.2.1 算术逻辑单元

作用、大致原理

  • ALU(Arithmetic and Logic Unit):用于实现算术运算、逻辑运算和一些辅助功能(移位、求补)等。
  • ALU有A、B两个输入信号,一个F输出信号,一些控制输入信号。
  • 具体实例:
    74181芯片
    74181芯片是一个4位ALU,右侧的输入就是控制信号,用来控制当前的运算。

电路基础知识

  • 基本逻辑运算:
    当一个逻辑运算中同时出现&和|,先算与,再算或。
  • 复合逻辑:
    与非:A和B先与再非
    或非:A和B先或再非
    异或:可以用与、或符合而来,A、B只有一个为1是结果为1
    同或:异或取反

加法器的实现

一位全加器

  • 本位有两个参与运算的数\(A_i\)和\(B_i\),还有低位进位\(C_{i-1}\), 本位的和记为\(S_i\)
  • 加法是一位一位的加,本位的输出结果&S_i&:输入中有奇数个1.

\[S_i = A_i \oplus B_i \oplus C_{i-1} \]

向高位的进位\(C_i\)是输入中至少有2个1.

\[C_i = A_iB_i + (A_i \oplus B_i)C_{i-1} \]

其中\(A_iB_i\)表示两个本位都是1, +表示或, \((A_i \oplus B_i)C_{i-1}\)表示两个本位中有一个1,低位进位为1.

  • 一位全加器英文缩写为FA(Full Adder),图示如下:
    一位全加器
  • 如果利用一位全加器实现多位加法?
    • 串行全加器:
      在一位全加器的基础上增加一个进位触发器,用来保存进位位。
      整个运算过程只有一个一位全加器,数据逐位串行送人加法器中进行运算。进位触发器用来寄存进位信号,以便参与下一次运算。
      串行加法器的图示如下:
      串行加法器
      缺点:效率较低。
    • 串行进位的并行加法器:
      串行进位的并行加法器
      把n个全加器串接起来,即可进行n位相加。
      进位信息是串行的一位一位往前进的。
      串行进位也叫行波进位。
    • 并行进位的并行加法器:
      串行进位的加法器计算速度受进位信号产生速度的影响。并行进位的并行加法器解决的问题是如何让进位计算的更快。
      进位信号的计算可以有如下递推公式:
      进位信号递推公式
      一直向下递推最终可以推到\(C_0\)
      通过对逻辑表达式的化简,最终可以用\(C_0\)和\(A_iA_{i-1}...A_1\), \(B_iB_{i-1}...B_1\)来表达\(C_i\)
      由此设计出的电路每一位的进位几乎是同时产生的,提高了效率。但是每递推一次,表达式越复杂所以一般推到\(C_4\),每4位之间串行,4位之内并行。

2.2.2 补码加减运算器

  • n bit补码X + Y,直接相加即可。
  • n bit补码X - Y,将补码Y全部按位取反,末位+1,得到\([-Y]_补\),减法变加法。
  • 补码的加减运算器:
    Y是通过一个多路选择器连接的ALU,在控制信号为0(加法)时,Y直接输入到ALU中,低位进位与多路选择器的控制信号相连,数值为0。当多路选择器的控制信号为1(减法)时,Y取反输入ALU,\(C_{in}\)值为1,相当于X + (-Y)(Y按位取反) + 1。
    无符号数的加减运算也可以用同样的电路。

加减运算和溢出判断

原码的加法运算

  • 正 + 正:绝对值做加法,结果为正。
  • 负 + 负:绝对值做加法,结果为负。
  • 正 + 负:绝对值大的数减绝对值小的数,结果符合与绝对值大的保持一致。
  • 注:加数和被加数的符号相同时,结果可能出现溢出。

原码的减法运算

核心思路是转变为加法运算。

  • 正 - 正 = 正 + 负
  • 正 - 负 = 正 + 正
  • 负 - 正 = 负 + 负
  • 负 - 负 = 负 + 正

溢出判断

  • 溢出分为上溢和下溢,如下图所示:
    溢出示意图
    当“正 + 正”超出正数区表示的上限时,发生上溢,上溢的结果是“正 + 正 = 负”
    当“负 + 负”小于负数区表示的下限时,发生下溢,下溢的结果是“负 + 负 = 正”

  • 下图所示为补码加法的另一种理解:
    3位补码数轴
    上图所示位3位补码所能表示的8个数,一个数加另一个正数X,可以理解为向右移动X个数。例如2 + 2,即从2向右移两位,超出部分绕到最左边。2向右移一位是3,再移是-4,所以3位补码2 + 2计算结果的真值为-4,发生溢出。

  • 溢出判断方法一:
    \( V = A_sB_s \overline{S_s} + \overline{A_s} \overline{B_s}S_s \)
    解释:\(A_s\)、\(B_s\)表示两个参与运算数字的符号位。\(S_s\)表示结果的符号位。该逻辑表达式的含义为A、B为正结果为负,或A、B为负,结果为正。
    V = 0表示无溢出;
    V = 1表示有溢出。
    写逻辑表达式的作用是未来便于硬件电路的实现。

  • 溢出判断方法二
    根据数据位进位情况判断溢出。设符号位的进位为\(C_s\),最高数值位的进位为\(C_1\).
    最高数值位的进位指数值为计算时算到最高位有没有向前进位。
    符号位的进位即两个符号位同时为1时,相加会出现进位1,否则没有进位。
    溢出情况如下表:

\(C_s\) \(C_1\)
上溢 0 1
下溢 1 0

即\(C_s\)和\(C_1\)不同时发生溢出。
解释一下上面表格:当符号位进位为零可能有3种情况:正 + 正、正 + 负、负 + 正。其中只有正 + 正可能出现溢出,当正 + 正的数值位有进位时,整体发生溢出(上溢);当符号位的进位为1时,说明是负 + 负,负 + 负的情况下符号位相加结果为0,向高位进1,若数值位有进位,则进的这一位将写在符号位上,符号位为1,得到“负 + 负 = 负”的合法结果。但是如果数值位没有进位,则符号位为0,出现“负 + 负 = 正”的下溢情况。
逻辑表达式如下:
\(V = C_s \oplus C_1\)
V = 0, 无溢出
V = 1,溢出

  • 溢出判断方法三
    采用双符号位,正数符号00,负数符号11,计算结果符号位为01时上溢,计算结果符号位为10时下溢。
    这个方法的原理和方法二是一样的。
    另一种解释:双符号为的第一位表示本应得到的正负情况,第二位表示实际得到的正负情况,01是结果本应是正的,实际是负的,判断为上溢。10反之。
    双符号位的补码又称:模4补码
    单符号位的补码又称:模2补码
    双符号位在计算机中的实际存储时也只存一个符号位,在运算时会复制一个符号位。

符号扩展

  • 正整数的扩展原、反、补都是一样的,直接在前面加0.
  • 负整数的扩展如下表:
扩展方式 负整数 扩展结果
原码 符号位后加0 1,1011010 1,00000000 1011010
反码 符号位后加1 1,0100101 1,11111111 0100101
补码 符号位后加1 1,0100110 1,11111111 0100110
  • 正小数的符号扩展原、反、补都是一样,在小数末尾加0.
  • 负小数的符号扩展如下表:
扩展方式 负小数 扩展结果
原码 末尾填0 1.1011010 1.1011010 00000000
反码 末尾填1 1.0100101 1.0100101 11111111
补码 末尾填0 1.0100110 1.0100110 00000000

标志位的生成

加法器除了计算相加结果之外,还可以生成4个标志位。

OF(Overflow Flag)

  • 溢出标志。溢出时为1,否则为0.
  • 仅在有符号数的加减运算中有意义。对无符号数无意义。
  • 硬件计算方法:\(OF = 最高位产生的进位 \oplus 次高位产生的进位\)

SF(Sign Flag)

  • 符号标志。结果为负时为1,否则为0.
  • 硬件计算方法:\(SF = 最高位的本位和\)
  • SF对无符号加减计算无意义。

ZF(Zero Flag)

  • 零标志。运算结果为0时为1,否则为0.
  • 硬件计算方法:两个数的运算结果有n位,只有n位全为0,ZF = 1.

CF(Carry Flag)

  • 进位/借位标志。进位/借位时置1,否则为0.
  • 仅对无符号数加减法有意义。
  • 硬件计算方法:
    \(CF = 最高位产生的进位 \oplus sub, sub = \begin{cases} 0,表示加法\\ 1,表示减法 \end{cases}\)
  • 无符号数借位的含义是两个数计算结果用补码来读真值是负的,但是无符号数不会有负的,所以解释为借位。

2.2.3 定点数的移位运算

移位:通过改变各个数码位和小数点的相对位置,从而改变各数码位的位权。可以用移位运算实现乘法、除法。

算术移位(常考)

原码的算术移位

符号位保持不变,仅对数值位进行移位。
相当于乘或除\(2^n\)

  • 右移:符号位不动,高位补0,低位舍弃。若舍弃的位是0则相当于除2;若舍弃的不是0,则会丢失精度。
  • 左移:符号位不动,最高位舍弃,低位补0。若舍弃的位 = 0,则相当于乘2;若舍弃的位不等于0,则会出现严重误差。

反码的算术移位

  • 正数和原码一样。
  • 负数的反码算术移位:
    右移:符号位不动,高位补1,低位舍弃。
    左移:符号位不动,低位补1,高位舍弃。

补码的算术移位

  • 正数跟原码一样。
  • 负数的补码算术移位:
    右移:符号位不动,高位补1,低位舍弃。
    左移:符号位不动,低位补0,高位舍弃。

算术移位的应用

例:求-20 * 7
解:
\((-20) \times 7 = (-20) \times (2^2 + 2^1 + 2^0)\)
也就是(-20) + (-20)算术左移1位 + (-20)算术左移2位。

逻辑移位

  • 逻辑右移:高位补0,低位舍弃。
  • 逻辑左移:低位补0,高位舍弃。
  • 可以看作是对无符号数的算术移位。

循环移位

把移出去的为补到另一头。

  • 带进位位的循环移位:
    带进位位的循环移位
    进位位也参与移动,用来记录数据进位。相当于给原本的数据多添了一位。
  • 适用于把数据的高位和低位进行高低字节的调换。

2.2.4 乘法运算

乘法运算的实现思想

手算二进制的乘法和手算十进制的乘法过程相同。
考虑用机器实现,会有一些问题:

  • 实际数字有正有负,符号如何处理?
  • 乘积的位数要扩大一倍,如果处理?
  • 每位的位积都要保存下来最后统一相加吗?

原码的一位乘法

  • 符号位单独处理:\(符号位 = X_s \oplus Y_s\)
  • 数值位取绝对值进行乘法计算。
  • 乘法运算实现方法:先加法再移位,重复n次。
    在正式进行乘法之前,ACC置0,乘数存在MQ内,被乘数存在X中,当乘数最低为位1时,(ACC + X) -> ACC;当乘数最低位为0,ACC不加X。之后ACC和MQ整体逻辑右移一位,重复之前的过程。
    乘法过程
    上图中红色的部分可以称为部分积。
    定点小数的小数点隐藏在符号位后面,计算的时候可以不用考虑。
    最终计算结果ACC中保留的是乘积高位,MQ中保留乘积低位。
  • 原码一位乘法(手算模拟):
    原码一位乘法模拟过程
    上述过程中,被乘数和乘数采用双符号位,但是实际做题的时候采用单符号位也可以。
  • 本节中采用小数作为例子,整数的原理相同。

补码的一位乘法

  • 补码一位乘法和原码一位乘法的过程相似,区别是:
    • 补码需要进行n轮加法、位移,最后比原码再多一次加法。
    • 原码每次加法可能加0或\(+[|X|]_原\),补码依据MQ中的最低位和一个辅助位判断,每次可能加0、\(+[X]_补\)或\(+[-X]_补\)。
      • 辅助位 - MQ中的最低位 = 1时,\([ACC] + [X]_补\)
      • 辅助位 - MQ中的最低位 = 0时,\([ACC] + 0\)
      • 辅助位 - MQ中的最低位 = -1时,\([ACC] + [-X]_补\)
    • 原码每次逻辑右移,补码每次算术右移。
    • 原码的乘数符号位不参与运算,补码乘数符号位参与运算。
  • 硬件构成:
    补码一位乘法硬件构成
    MQ中的实际最低位为新增的辅助位,由于MQ增加了一位,其余寄存器(ACC, X)也要随之增加一位(被乘数采用双符号位的补码,乘数采用单符号位的补码)。
    可能会有一个辅助电路实现\([X]_补\)到\([-X]_补\)的转换。
  • 采用Booth算法求\(X \times Y\):
    Booth算法举例

2.2.5 除法运算

除法运算的思想

手算二进制除法:
例:设机器字长为5为(含一位符号位,n = 4),x = 0.1011, y = 0.1101, 求x/y:
解:可以先把除数和被除数都乘\(2^4\),变成正数。
除法竖式

原码除法:恢复余数法

  • 运算器的结构:
    恢复余数法
  • 实现方法:上商0/1,得到余数,余数末尾补0.
  • 符号位单独处理:\(符号位 = X_s \oplus Y_s\)
    数值位取绝对值进行除法运算。
  • ACC中存被除数,通用寄存器(X)中存除数的值。MQ中存最后的商,一开始全部取0. MQ的最后一位是当前要确定的商的位置。
  • 每位的商计算机都会先默认为1,ACC里的被除数加除数的相反数的结果存到ACC中去。ACC的结果如果是正的,则这一位就是商1。ACC的结果如果是负的(符号位为1),说明这一位商不该是1,就把MQ末位的值改为0,ACC里的数再加除数。之后再把ACC和MQ里的所有值统一逻辑左移一位。
  • 如果最后一位商1后发现需要恢复余数,则还需把最后一位商改成1,再把ACC里的值加上除数。
  • 得到的余数还要再乘\(2^{-n}\),才是最终余数的值。
  • 注:计算过程中如果出现要加(-Y),加的都是补码。

原码除法:加减交替法(不恢复余数法)

  • 由于恢复余数发的过程较为麻烦,所以可以做一些优化,改为不恢复余数的除法。原理就是恢复余数法恢复余数后,商0,还要逻辑左移1位,再减去除数。这个过程简化就可以直接变成商0,不恢复余数,左移后加上被除数的补码。
  • 符号位的确定也需要单独解决:\(Q_s = X_s \oplus Y_s\)
  • 最终余数的正负性和商相同。
  • 加、减执行n + 1次,每加一次确定一位商;左移n次(最后一次加减完不移位),最终可能还要多加一次。
  • 最后说明:这里讨论的是定点小数的除法,最终结果也是定点小数。所以被除数应该要小于除数,否则结果会大于1,而定点小数无法表示大于1的范围。原码除法通过第一位的商来判断被除和除数的大小。

补码除法:加减交替法

  • 补码除法:符号位参与运算,被除数/余数、除数采用双符号位。
  • 在写补码的时候,写的是除数的补码,而不是除数绝对值的补码。因为除数的符号位直接参与运算。
  • 第一步:判断被除数和除数是否同号,同好则被除数减去除数,异号则被除数加除数,得到一个新的余数。
  • 如果除数和余数同号,商1,余数左移一位减去除数。
    如果余数和除数异号,商0,余数左移一位加除数。
    如此重复n次。
    最后一位的商恒为1,不管同号异号(主要是为了省事)。

除法运算的总结:

除法类型 符号位是否参与运算 加减次数 移位方向 移位次数 上商、加数原则 说明
原码加减交替法 N+1或N+2 N 余数的正负 若最终余数为负,需要恢复余数
补码加减交替法 N+1 N 余数和除数是否同号 商末位恒置1

2.2.6 C语言类型转换

C语言中的定点整数都是用补码的形式存储的

void main(){
    short x = -4321;
    unsigned short y = (unsigned short)x;

    int a = 165537, b = -34991;
    short c = (short)a, d = (short)b;

    // short x = -4321;
    int m = x;
    unsigned short n = (unsigned short)x;
    unsigned int p = n;
}
  • 在上述代码中无符号数与有符号数的转变不改变数据内容,只改变解释方式。
    x = -4321 = \((1,110\space 1111\space 0001\space 1111)_2\).
    y = \((1110\space 1111\space 0001\space 1111)_2\). = 61215.
  • 长整数转短整数:高位截断,保留低位。
    a = 0x0002 86a1
    c = 0x86a1 真值-31071
    b = 0xffff 7751
    d = 0x7751 真值30545
  • 更短的数据转为更长的数据:符号扩展。
    x = 0xef1f
    m = 0xffff ef1f 真值-4321.
    n = 0xef1f 真值61215
    p = 0x0000 ef1f 真值61215

2.2.7 数据的存储和排列

大小端模式

对于一个4字节的int:
19088743D
01 23 45 67H
0000 0001 0010 0011 0100 0101 0110 0111B

  • 其中,十六进制的01为这个数的最高有效字节(MSB)。67为最低有效字节(LSB)。
  • 多字节的数据在内存中一定是占连续的几个字节的。
    一般有大端、小端两种存储方式。
    其中大端方式便于人类阅读,每个字节按照地址从低到高存储。低地址存储最低有效字节,高地址存最高有效字节。
    小端方式逆过来,最高有效字节在低地址,最低有效字节在高地址。

边界对齐

现代计算机通常是按字节编址,即每个字节对应1个地址
通常也支持按字、按半字、按字节寻址。
假设存储字长为32位,则1个字 = 32bit,半字 = 16bit。每次访存只能读/写1个字。
边界对齐的存储方式和边界不对齐的存储方式如下图:
边界对齐、不对齐
边界对齐读取方便但是有点浪费空间,边界不对齐方式节约空间,但是读取过程比较浪费时间。

2.3.1 浮点数的表示

  • 科学计数法的表示方式:
    科学计数法
    阶符负责标记小数点移动端方向,阶符为正,小数点后移,阶符为负,小数点前移。
    阶符的数值部分表明小数点要移动多少位。
    尾数数符表示整个数值的正负。
    尾数的数值部分位数越小精度越小。

浮点数的表示

  • 阶码(E):常用补码或移码表示定点整数。反应浮点数的表示范围及小数点的实际位置。
  • 尾数(M):常用原码或补码表示的定点小数。数值部分的位数N反应浮点数的精度。
  • 二进制浮点数的真值:\(N = r^E \times M\),其中r为阶码的底,通常是2,也可以取\(2^i\).
    例:阶码、尾数都用补码表示,求a, b的真值。
    a = 0,01;1.1001
    b = 0,10;0.1001
    解:a的尾数的原码表示对应的二进制真值为:-0.0111,a的真值 = \(2^1 \times (-0.0111) = -0.111\)
    b的阶码010对应真值为+2.尾数0.01001对应真值+0.01001,b的真值 = \(2^2 \times (+0.01001) = +1.001\)
    注:a有3位阶码和5位尾数,在1B的存储空间里可以刚好存下;但是b有3位阶码和6位尾数,在1B空间内存不下,会使精度降低。如何能在有限的空间内尽可能高的提高浮点数的精度呢?这需要进行浮点数的规格化。

浮点数尾数的规格化

在上面例子中,b = \(2^2 \times (+0.01001) = 2^1 \times (+0.1001)\)
即将尾数算术左移一位,阶码-1,这个过程称为左归。
同理,右归是当浮点数运算结果尾数出现溢出(双符号位为01或10)时,将尾数算术右移1位同时阶码+1.

  • 注:采用双符号位的好处是出现溢出还可以挽救。
  • 规格化浮点数的特点:
  1. 用原码表示的尾数进行规格化:
    正数为0.1....的形式,其最大值表示为0.11...1; 最小值表示为0.10...0;所以尾数的表示范围为\(1/2 \leq M \leq (1-2^{-n})\)
    负数为1.1....的形式,其最大值表示为1.10...0; 最小值表示为1.11...1;所以尾数的表示范围为\(-(1-2^{-n} \leq M \leq -1/2)\)
  2. 用补码表示的尾数进行规格化:
    正数和原码相同。
    负数:计算机规定,补码表示的负数尾数数值位的第一位必须是0,才算合法的规格化,其最大值表示为1.01...1; 最小值表示为1.00...0.

例:例题
解:将尾数算术左移3位,低位补0.
尾数变为1.0100000,左归了3次,阶码-3,变为0011.

  1. 浮点数的溢出:
    浮点数的溢出
    如果出现正下溢或负下溢的情况通常当作机器数的0处理。
    出现正上溢或负上溢,则抛出异常。

2.3.2 IEEE 754

IEEE 754是浮点数的一个标准

移码

  • 在IEEE 754标准中,阶码用移码表示。
  • 移码是在补码的基础上将符号位取反,只能用于表示整数。
  • 移码的定义:移码 = 真值 + 偏置值
    n位移码的偏置值一般为为\(2^{n-1}\),也可以取其他值。在IEEE 754标准中,规定阶码用移码表示,偏置值设为\(2^{n-1} - 1\)

IEEE 754标准

  • IEEE 754标准的浮点数格式如下图所示:
    IEEE 754标准的浮点数格式
  • IEEE 754的浮点数格式规定如下表:
类型 数符 阶码 尾数数值 总位数 偏置值
float 1 8 23 32 7FH/127
double 1 11 52 64 3FFH/1023
long double 1 15 64 80 3FFFH/16383
  • 尾数部分用源码表示,规格化希望原码最高数值位为1,所以在IEEE 754标准中,默认原码的最高数值位为1,这样float的尾数数值位虽然有23位,但是实际可以表示24位数。
    表中每个数据类型的阶码、尾数、总位数需要记住,考试不会给。
  • 例:float:1000 0001 1000 1010 0101 0000 1000 0000
    解:最前面的1表示整个数的正负
    阶码真值 = 移码 - 偏移量
    最终,这个浮点数的真值为:

\[(-1)^s \times 1.M \times 2^{E - 127} \]

  • 例:将十进制数-0.75转换为IEEE 754标准的单精度浮点数格式表示:
    解:\((-0.75)_{10} = (-0.11)_2 = (-1.1)_2 \times 2^{-1}\)
    移码 = 阶码真值(补码表示) + 偏移量(补码表示)
    -1的解码表示为1111 1111(-1) + 0111 1111(127) = 0111 1110(留足8位)
    -0.75 = float:10111 1110100 0000 0000 0000 0000 0000

  • 例:IEEE 754标准的float = C0 A0 00 00 H的十进制是多少?
    解:C0 A0 00 00 H对应二进制:1100 0000 1010 0000 0000 0000 0000 0000
    数符 = 1
    移码 = 100 0000 1
    尾数 = 1.010 0000 0000 0000 0000
    解码真值 = 移码 - 偏移量
    = 1000 0001 + 1000 0001
    = 0000 0010
    = 2
    对应十进制 = \(N = (-1) \times 2^2 \times 1.01 = -4 \times 1.25 = -5\)

  • IEEE 754 float能表示的最小绝对值和最大绝对值分别是多少?

    • 最小绝对值:尾数全0,阶码真值最小-126,对应移码机器数0000 0001,此时整体的真值为\((1.0)_2 \times 2^{-126}\)
    • 最大绝对值:尾数全1,阶码真值最大127,对应移码机器数1111 1110,此时整体的真值为\((1.111...11)_2 \times 2^{127}\)
    • 注:IEEE 754的移码全零和全一是特殊值,所以这里阶码真值最小到-126,最大到127.
    • 如果阶码全为0,默认尾数乘2的-126次方,但是尾数默认省略的首位1变成0,也就是阶码全为0时,可以表示绝对值更小的数。
    • 如果阶码全为0,尾数也全为0,表示真值\(\pm 0\)
    • 当阶码全为1,尾数全为0,表示无穷大\(\pm \infty\)。当计算过程中出现正上溢或负上溢时,结果会被记为\(+\infty\)或\(-\infty\)。
    • 当阶码全1,尾数不全为0时,表示非数值“NaN”(Not A Number)。

2.3.3 浮点数的运算

浮点数的加减运算

浮点数加减运算的步骤:

  1. 对阶:阶数小的向阶数大的转换(因为计算机内部,尾数是定点小数,如果阶大的转阶小的,尾数可能表示不下。)
  2. 尾数加减:将尾数进行相加
  3. 规格化:保证尾数是规格化的
  4. 舍入:由于浮点数的位数是有限的,超出有效部分的需要被舍弃。
  5. 判溢出:如果阶码的值超出规定范围,则判断溢出。
  • 例:已知十进制数X = -5/256、Y = +59/1024,按机器补码浮点运算规则计算X-Y,结果用二进制表示。浮点数格式如下:阶符取2位,阶码取3位,数符取2位,尾数取9位。(这个不是IEEE 754标准)

  • 解:
    转换格式:
    5D = 101B
    1/265 = \(2^{-8}\)
    \(X = -101 \times 2^{-8} = -0.0101 \times 2^{-5} = -0.101 \times 2^{-101}\)
    59D = 11 1011B
    1/1024 = \(2^{-10}\)
    \(Y = +111011 \times 2^{-10} = +0.111011 \times 2^{-4} = +0.111011 \times 2^{-100}\)
    X阶码-101转为补码:11 011(双符号位)
    X尾数-0.101原码是1.101,补码为11.0110 0000 0
    综上:X = 11011,11.011000000;
    同理,Y = 11100,00.111011000。
    对阶
    使两个数的阶码相等,小阶向大阶看齐、尾数右移1为,阶码+1.
    求阶差:\(\Delta E_补 = 11011+00100 = 11111 = -1\)
    对阶:X:11011,11.011000000 -> 11000,11.101100000.(算术右移)
    尾数加减:最终结果10.110001000(发生溢出,但是还可以挽救)
    规格化
    尾数算术右移,阶码加一。得到结果:
    X-Y:11101,11.011000100
    舍入:无舍入
    判溢出:阶码没有溢出,结果真值为\(2^{-3} \times (-0.1001111)_2\)

  • 浮点数加减运算——舍入:

    • 0舍1入法:类似四舍五入,尾数是0直接舍弃,尾数是1末尾+1.
    • 恒置1法,尾数右移时,不论丢掉的最高数值位是0还是1,都使右移后的尾数末位恒置1. 这种做法可能使尾数变大或变小。

浮点数到定点数的强制类型转换

不同字长的机器各类型数据位数如下表:

类型 16位机器 32位机器 64位机器
char 8 8 8
short 16 16 16
int 16 32 32
long 32 32 64
long long 64 64 64
float 16 32 32
double 64 64 64
  • 无损类型转换(32位机):char -> int -> long -> double(64位的long转double会有精度的丢失)
    float -> double
  • 32位机器,int转float:
    int表示整数,1位符号位,31位数值位。
    float表示整数及小数,1位符号位,8位阶码位,23+1(隐藏的首位1) = 24位数值位。
    所以int -> float可能损失精度。
    float -> int可能溢出及损失精度。

标签:计组,符号,尾数,补码,笔记,times,第二章,原码,运算
From: https://www.cnblogs.com/jacaranda/p/18305537

相关文章

  • redis笔记2
    redis是用c语言写的,放不频繁更新的数据(用户数据。课程数据)Redis中,"穿透"通常指的是缓存穿透(CachePenetration)问题,这是指一种恶意或非法请求直接绕过缓存层,直接访问数据库或其他持久存储的情况。具体来说,Redis缓存穿透是指请求的数据在缓存中不存在,导致每次请求都要访问数......
  • 从零开始:利用阿里云 OSS 轻松同步你的思源笔记
    引言在数字时代,数据的安全与同步变得尤为重要。思源笔记作为一款隐私优先的个人知识管理系统,如何通过阿里云OSS进行数据同步?本文将为基础小白详细讲解步骤,让你轻松上手。请务必先备份数据,重要的事情说三遍!创建存储桶登录阿里云官网,使用支付宝扫码登录。打开oss存储,......
  • 计算机组成复习——第二章机器指令知识点总结
    ......
  • GZERec论文阅读笔记
    GenerativeAdversarialZero-ShotLearningforCold-StartNewsRecommendation论文阅读笔记Abstract现存的问题:​ 新闻推荐模型极其依赖用户与新闻文章之间的交互信息来进行个性化推荐。因此,冷启动问题(CSP)是其面临的最严峻挑战之一。对于新用户或新新闻,它们的性能会急剧下......
  • java学习笔记
    //单行注释/**/多行注释/** */文档注释byte:-128~127short:正负三万int:正负21亿long:如果表示的数超过int需要加L 123456789123456Lfloat:后面加fdouble:char:单引号引起来的单个字符增强for循环:for(intnum:arr)创建新的构造器,要保留空构造器,构造器也......
  • 动手学深度学习6.4 多输入多输出通道-笔记&练习(PyTorch)
    以下内容为结合李沐老师的课程和教材补充的学习笔记,以及对课后练习的一些思考,自留回顾,也供同学之人交流参考。本节课程地址:21卷积层里的多输入多输出通道【动手学深度学习v2】_哔哩哔哩_bilibili本节教材地址:6.4.多输入多输出通道—动手学深度学习2.0.0documentation(......
  • DIY系列——自制简易笔记本电脑散热器
    前言:为什么要自制笔记本电脑散热器?夏天到了,电脑的使用频率也在增加。尤其是笔记本电脑,长时间运行后很容易发热,影响性能和寿命。市场上有很多散热器产品,但价格不菲且效果参差不齐。如果你动手能力强,又想节省一笔开支,自制一个简易的笔记本电脑散热器是一个不错的选择。材料准备......
  • 信创学习笔记(三),信创之操作系统OS思维导图
    创作不易只因热爱!!热衷分享,一起成长!“你的鼓励就是我努力付出的动力”title!!#f1c232点击上方蓝色小字即可一键关注!!!!#f1c232创作不易只因热爱!!:::primary!18热衷分享,一起成长!:::^**你好呀,我是卫码士。一个医信行业工程师,喜欢学习,喜欢搞机,喜欢......
  • 杂乱无章的sql注入学习笔记(应该会持续更新)
    关于注入点:注入点不仅仅有.php?id=xxx只要是后端有交互的点都可能存在sql注入,黑盒情况下不知道后端,所以得fuzz,有的数据库会对你的cookieua进行查询操作,甚至是别的请求头,所以要都fuzz试试.甚至对图片的查询操作都可能存在注入点,思路要打开.学习sql语句:参考SQL通配符......
  • Java JNI 学习笔记
    JavaJNI学习笔记JNI(JavaNativeInterface)是Java提供的一种接口,使得java代码可以与其他语言(如C和C++)编写的代码进行交互。具体来说,JNI允许你在Java中调用本地(Native)代码,或者从本地代码调用Java方法。基本概念jni.h:这是JNI的头文件,使用javac生成,定义了JNI......