玩命加载中 . . .

计算机中信息的表示与运算


计算机存储数值采取编码形式,常见的编码有四种:

  • 原码
  • 补码
  • 反码
  • 移码

先导概念

  • 真值:即真正的数值,是带有正负号的一种数,人类可以识别。
  • 机器数:将符号数值化之后的结果,计算机可以识别。
  • 定点数
    • 定点整数:默认小数点在数值最低位之后
    • 定点小数:默认小数点在符号位与数值最高位之间
    • 有符号数:最高位为符号位,次高位为数值位
    • 无符号数:最高位就为数值位

原码

最简单的一种码,即真值符号化的最简单的结果,极似真值。
求数的原码很简单:

  • 得到数的二进制表示形式
  • 确定符号位,整数为0,负数为1
  • 注意机器字长(寄存器位数),补零

在书写上,若逗号,放在了符号位和数值最高位之间,则是一个定点整数;
若小数点.放在了符号位和数值最高位之间,则是一个定点小数。

原码表示范围

注意原码的表示范围。原码表示无符号数时,表示区间与有符号数有差异。

0的原码

另注意:
0的原码有俩,因为从真值上看,+0和-0都是0,但是其机器码(原码)却有差别:
+0 —- 0,0000000B
-0 —- 1,0000000B

补码

补码的出现,首先就是为了找到一个等价于某一个数,以方便运算。

补码计算公式
关于补码公式,教材上有完整的表述,此外注意二进制数的两种特殊形式:
2^n - 1 = 11…1
2^n = 100…0

补码的二义性

由于补码对定点整数和定点小数的公式不同,因此,以-1为例,-1作为定点整数和定点小数时,会得到两种不同的结果!具体按公式来。

补码和原码的对比现象

一个负数的原码从它的低位算起,
①遇到第一个“1”时,原码与补码是相同的。
②超过这个“1”直至符号位之间的那段数位,原码与补码是相反的。

求补码快捷方式

  • 对于正数,其补码和原码一致
  • 对于负数,其补码由原码除符号位外,各位取反,然后末尾加一,得到
  • 已知某真值的补码,求其相反数的补码,则将包括符号位在内的补码,各位取反,末尾加一,得到

反码

移码

移码公式

移码公式说白了,就是将真值往高位方向移动一定的数值,主要用于需要对数据进行大小比较的场合。
如果真值有n位,就在真值基础上加上100…0(n个0)即可。

定点数与浮点数的表示

定点数

浮点数

借助数学中的科学记数法,将浮点数转化为定点数。
一个浮点数可以表示为: N = M × R^E
其中,

  • M称为尾数,一般取一个定点小数
  • R称为基值
  • E称为阶码

规格化表示

为了利用尾数所占的二进制数位来表示最多的有效数字,浮点数一般采用“规格化形式”:
也即尾数绝对值的最高位必须为1,即尾数绝对值必须大于或者等于1/R。

当规格化过程中,浮点数阶码小于最小阶码时,称发生“下溢”。

浮点数的表示范围

以原码表示,分析即可。
最大正数
最小正数
最大负数
最小负数

长实数与实数

长实数:64位浮点数
实数:32位浮点数

定点数的运算

逻辑运算

移位运算

明确两个概念:
算术移位:有符号数的移位
逻辑移位:无符号数的移位

算术移位规则

算术移位

最首要的规则,就是符号位不变。

  • 对于正数,原码、补码、反码的移位只需补0即可
  • 对于负数
    • 原码,左移右移均补0
    • 补码,左移补0,右移补1
    • 反码,左移右移均补1
逻辑移位

由于逻辑移位处理的是无符号数,所以相对而言比较简单,规则就是:
移出的空位均补0

加法与减法运算

补码的引入,使得定点数的加、减运算都被统一成了加法运算,所以对于加减运算,我们都采取补码形式。
此外,补码运算也不需要单独处理符号位,它在运算过程中自然形成,这样一来大大简化了硬件设计。

公式

[X + Y]补 = [ X ]补 + [ Y ]补
[X - Y]补 = [ X ]补 + [ -Y ]补
对于整数,结果需要对2^(n+1)取模;
对于小数,结果需要对2取模。
也即对超出字长的数位丢弃。

公式的证明
分四种情况来证明即可,分类讨论,注意运用补码公式(含取模)!

溢出

导致溢出的原因,就是计算机字长是固定的,数值位最高位产生的进位1被字长最高位吸收,而这个“1”属性本来是数值,而现在却被当做了符号。

同号操作数相加时,可能“溢出”;
异号操作数相加时,绝对不会“溢出”。

溢出的判断

两个数符号相同,而结果的符号不同,这时一定发生了溢出。

硬件实现:最高有效位的进位 和 符号位的进位作异或操作,若结果为1,则溢出了。

双符号位判断法:符号位由原来的一位变成了两位,操作之后,若双符号位取值不同,表示发生了“溢出”。

乘法操作

笔算乘法的改进过程

首先,对于乘积式A×B,约定A为被乘数,B为乘数。
定义两种说法:部分积与单次乘数。
部分积:是指每一次乘法得到的结果,最后的积由每一个部分积累加而成。
单次乘数:每一次取B的一个数位,这个数位上的数就是单次乘数。

过程大致如下:

  1. 初始状态,部分积为0;
  2. 取B的最低位作为乘数,与A相乘后的结果(要么是0要么是A)与部分积相加,更新部分积;
  3. 部分积连同B一起右移一位(即部分积的最低位移到乘数的最高位,乘数的最低位丢失),重复第2~3步即可。

从硬件实现角度看,完成整个乘法需要三个寄存器(分别存放被乘数、乘积的高位、以及乘数和乘积的低位),一个全加器和其他相应的电路。

原码的一位乘法

符号位:被乘数和乘数的符号位作异或操作;
数值位:按照上述笔算乘法的改进过程即可。

原码的二位乘法
补码的一位乘法

乘数为正数时,两数积的补码等于补码的积。
这里的加、移位操作都必须按照补码的规则来!
乘数为负数时,公式有些许不同。
运算过程大体与之前的一致。

除法

原码的除法

  • 商的符号位单独处理(异或)
  • 商的数值部分为绝对值相除

对于A÷B,我们以下的被除数,除数都是在原题基础上不考虑符号位的无符号数。
不恢复余数法:

  1. 初始状态商为0,被除数为A;
  2. 用被除数减去除数,也就是加上除数的相反数的补码,如果结果(即余数)为正,上商1,否则上商0(均在当前商的最低位);
  3. 如果上一步得到的余数为负数,那么需要加上除数,以将余数恢复为一个正数,如果为正数直接进行下一步了;
  4. 将得到的余数逻辑左移,同时当前的商也左移,重复第2~4步。

文章作者: 鹿卿
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 鹿卿 !
评论
  目录