数制和编码
为什么计算机使用二进制编码
- 二进制只有两种状态,元件制造成本低;
- 1 和 0 刚好提供了逻辑值“真”和“假”,方便实现逻辑运算;
- 编码和运算规则简单,方便通过逻辑门电路来实现。
进制转换
进位计数法
常见的进位计数法有十进制、二进制、八进制、十六进制等,一般逢 就进一位,这里的 被称为基数。
一般来说,二进制转换到八进制或十六进制比较简单,因为 、 都是 的倍数,只需要将二进制每三/四位分为一组,再将每组转换为对应进制的数即可。
对于其他进制而言,可以先将其转换为 进制,再进行转换。
将整数从十进制转换到任意进制需要用到 除基取余法 ,即除以要转换进制的基数,得到余数,并对商再次进行同样的操作,直到商为 ,最后将余数按照 从下到上 的顺序排列即可,如求 的二进制:
可以得到其二进制数为 .
对于小数,需要使用 乘基取整法,即乘以基数,取其整数部分,直到乘积为 或精度符合要求之后结束,最后按照 从上到下 的顺序排列。
位 进制和 进制数分别能表示 个数字,这也是计算机运算存在误差的原因,它表示仅有 的概率十进制数可以用二进制表示。
BCD 码
二进制编码的十进制数(),采用 位二进制数来表示 位十进制数(),此法可以使得二进制和十进制转换得以快速进行,但是有冗余状态。
常用 码:
- 码,有权码,即 ,若两个 码相加小于等于 ,则不需要修正,若大于 ,则需要加 修正,因为落在这个区间内为无效码。
- 余 码:无权码,在 码的基础上加 形成的,因此每个数都多余 ,这样相加就不需要修正了。
- 码,有权码,即 ,特点是大于等于 的 位二进制数中最高位为 ,小于 的最高位为 .
ASCLL 码
码使用指定的 位或 位二进制数组合来表示 或 种可能的字符。标准 码也叫基础 码,使用 位二进制数(剩下的 位二进制为 )来表示所有的大写和小写字母,数字 到 、标点符号,以及在美式英语中使用的特殊控制字符。其中: 及 (共 个) 是控制字符或通信专用字符,这些字符不可以显示。
常用的符号 码如下
符号 | 编码 |
---|---|
空格 | 20H |
1 | 31 H |
A | 41 H |
a | 61 H |
汉字编码
区位码:使用两个字节表示一个汉字,每个字节使用七位编码,将汉字和符号排列在一个表中,两个字节分别表示横纵坐标;
国标码:区位码的十六进制加上 ,这是为了兼容不支持汉字的机器,防止被转换为 中的控制字符;
汉字内码:国标码的十六进制加上 ,直接跳过 的范围。
汉字的内码有:
- GB2312-1980
- GBK
- GB18030-2000
- ISO/IEC10646-1、Unicode 2.0
定点数的编码表示
根据小数点的位置是否固定,计算机中有两种数据格式:定点表示和浮点表示。
常用定点补码整数表示整数,定点原码小数表示浮点数的尾数部分,移码表示浮点数的阶码部分。
定点整数和定点小数没啥好说的,第一位是符号位,其他是数值位,但是注意小数转换为补码时,最后的 不需要变为 ,如 应该先对最后一个 以前的数取反 ,即最后的 不变,再加一得到 .
定点整数/小数都是纯整数/小数,即只有整数/小数部分。
表示方法主要有 4 种:原码、补码、反码和移码。
原码:原码首位表示正负,其他位表示数值绝对值大小。
补码:原码的加减比较复杂,因此提出了补码来方便计算。 方式为 除了符号位按位取反再加 1,要求负数的原码只需要再次求补即可。
变形补码:又称 模4补码
,即用两个二进制位来表示数字的符号位,其余与补码相同,用 表示正,用 表示负,用变形补码进行加减运算时,当运算结果的符号位出现 ,则表示产生正/负溢。
原码有两个 ,正零()和负零();补码只有一个 (),补码()表示的是 ,即 ;可以认为,在补码中,原来的负零被分配到表示最小的数去了。
反码:负数则数值位取反即可。
移码:移码常用来表示浮点数的阶数,且 只能用来表示整数。 移码就是真值加了一个常数 ,其中机器字节长为 ,其和补码 符号位相反。
负数的反码/补码的数值部分越大/小,绝对值越小/大,真值越大/小,越靠近/远离 .
运算方法和运算电路
基本运算部件
计算机中运算器由 、移位器、状态寄存器和通用寄存器组成。 的核心是加法器。
一位全加器
全加器()是最基本的加法单元,输入为两个加数和低位传来的进位,输出为一个结果和进位。
和表达式为 ,进位表达式为
串行进位加法器
将一些全加器串联可以得到串行进位加法器,每一级的进位依赖于前一级的输出,因此整个计算过程是串行的,严重影响计算时间。
并行进位加法器
进位计算公式为
其中 ,分别表示生成()和传递(),生成表示是否要产生进位,传递表示是否要将低位的进位传递给高位。若两个加数都为 时,会产生进位;若存在加数为 ,低位进位为 ,则也会产生进位。
以四位加法距离,进位公式为
当位数太多时,电路会过于复杂,因此实际可以四位为一组,组内使用并行进位加法器,组间使用串行进位加法器或并行进位加法器(两级(多级)先行进位加法器)。
带标志加法器
可以用于带符号整数的加减运算,需要额外处理标志位信息。
溢出标志 ,符号标志为和的符号,零标志位 当且仅当 ,进位/借位标志 .
算术逻辑单元(ALU)
可以实现加减乘除、与或非、移位等操作, 的核心是带标志加法器。
接收两个 位操作数,一个进位,和一个操作控制 ,用于控制计算类型。
定点数移位运算
就是将数值整体左移或右移,超出的位数直接舍弃,并在空出的位置上添 或 ,循环移位就将超出的部分移动到空出的部分上。
算术移位
算术移位的对象是有 符号数,移位过程中符号保持不变;左移表示乘二,右移表示除以二;
对于正数而言,原码、补码、反码的移位都是添 ;
对于负数,原码仍旧是添 ,反码添 ,补码左移添 ,右移添 .
逻辑移位
即无视符号位,直接移动。
循环移位
循环移位分为 带进位标志位的循环移位(大循环) 和 不带进位标志为的循环移位(小循环),大循环就是进位标志位一起参与移位。
定点数的加减运算
补码加减运算规则
加法:补码直接相加,舍去高位。
减法:减数求负补码,转换为加法。
补码加减运算电路
要实现减法,需要在加法器的输入前加 位反向器进行取反,并使用一个二选一多路选择器控制,当信号 为 时,则认为做减法,二选一多路选择器选择取反的数据。 同时信号 一直作为进位传送给加法器,若是减法则起到取反之后加一的作用。
输出运算结果和标志位,零标志 表示结果为 ;溢出标志 对于有符号数表示溢出,对于无符号数无意义;符号标志 表示结果正负,对于无符号数无意义;进/借位标志 表示 无符号整数 的进位和借位,判断是否有溢出,做加法时, 表示产生进位,有溢出,实际输出不变,做减法时, 表示产生借位,有溢出,实际输出取反。
判别溢出
一位符号位
根据输入的符号位和结果的符号为进行判断, 则表示溢出。
也可以根据数据位的进位情况进行判断
若符号位的进位和最高位的进位相同,则无溢出
双符号位
基于这样的一个事实:若两个 位数字相加,则用 位来表示则一定不会溢出。 若两位符号相同,则无溢出,若为 ,则为正溢,,则为负溢。
进位判别法
最高位向符号位的进位 和符号位向更高位的进位 ,若不同,则发生溢出,可以表示为 .
定点数的乘除运算
乘法运算由累加和右移操作实现,可以分为原码一位乘法和补码一位乘法。
原码一位乘法
符号和数值分开求,符号运算使用异或 ,每次判断乘数的最后一位,如果为 ,则加上被乘数,否则不加,再右移一位;循环直到移动了 位, 为乘数的位数。
补码一位乘法
一个简单的方式是将最高位对应的十进制数值当作负数,其余位数的 当作正数,相加即可,如 1101
,其原码是 1011
,对应十进制是 ,直接通过补码计算为 .
该原理基于补码的定义,因此可以推出负数补码的一般式,即最高为负数;再通过裂项,得到与最后两位的关系,这就是 booth 算法;通过该关系可以得到四种情况:
次低位 | 最低位 | 操作 |
---|---|---|
0 | 0 | +0,右移一位 |
0 | 1 | + [x] 补,右移一位 |
1 | 0 | +[-x] 补,右移一位 |
1 | 1 | +0,右移一位 |
一些细节如下:
- 乘数被乘数和运算结果都是补码;
- 部分积和被乘数 使用双符号位,乘数 使用单符号;
- 初始部分积为 ,并且需要在 的末尾添加一个最低位 ;
- 累加 次,右移 次, 为 的初始长度。
恢复余数法和加减法
太麻烦了,略。
数据存储和排列
大端方式:高位在前面
小端方式:低位在前面
数据以边界对齐的方式存储,如 32 位计算机,字地址一定是 4 的整数倍,若所存储数据不符合要求,会通过填充空白字节进行存储,可以提高读取指令和取数的速度。
浮点数的表示和运算
浮点数指小数点的位置可以浮动,这样在位数有限的情况下,扩大了数的表示范围,又保持了数的精度。
浮点数格式为
其中 用于控制正负; 为一个二进制定点小数,称为尾数,一般使用原码表示; 是一个二进制定点整数,称为 阶码或指数 , 是基数,可以 约定 为 等,现在一般是 .
尾数反应浮点数的精度,阶码反应浮点数的表示范围。
溢出
运算结果大于最大正数被称为正上溢,小于最小正数被称为负上溢,在 0 到最小正数之间被称为正下溢,在 0 到最大负数之间被称为负下溢。
由于 754 可以使用非规格化尾数来表示浮点数,因此其表示下界更大,这可以看作是一种 渐进下溢;再下溢可以当 0 处理。
规格化
规格化的目的是为了充分利用尾数,使得有效数字能尽量占满尾数。 将尾数左/右移以达到尾数的最高位是有效数字的过程被称为左/右规。
规格化后的尾数大小应该满足 .
基数不同,尾数规格化的形式也不同,如基数为 ,则最高 位不同时为 .
IEEE 754 标准
32 位: 位符号、 位阶码、 位尾数,阶码偏置值为 .
64 位: 位符号、 位阶码、 位尾数。阶码偏置值为 .
临时浮点数: 位符号、 位阶码、 位尾数,总计 位。 阶码偏置值为 .
这里的移码并不符合一般一般移码的性质,一般移码的偏置值计算是 ,而 中的阶码偏置值需要再减去 : ,这样 和 就可以被空出来表示其他作用了 (这段可能有问题),因此其移码的实际范围是 ,如 .
若尾数为 ,当阶码全为 时表示正/负零,全为 表示正/负无穷;若尾数不为 ,而阶码全为 ,表示 ,为 表示没有隐藏 ,是非规格化数。
隐含基数为 .
对于规格化后的尾数,最高位总是 (若尾数使用补码表示,则需要分类讨论,若为负数,则最高位应该为 ,可以将逻辑化简为:符号位应该和最高位不同),因此将其再左移一位,可以将其隐藏,称为隐藏位,因此尾数实际有效位数会加 .
浮点数 有 位阶码和 位尾数,在深度学习领域经常会因为范围不够导致溢出,因此引入了 用于表示更大的范围,其拥有 位阶码和 位尾数,并且其表示范围和 对齐,因此可以进行混合精度训练;
此外还有 ,其范围也和 对齐,使用相同的 位阶数,保持范围不变,而尾数则使用和 相同的 位,可以良好的兼容二者,并且提高速度。