计算机的运算要领
2019-11-18杂谈搜奇网60°c
A+ A-盘算机的运算要领
无标记数
盘算机中的数存放在寄存器中,通常将寄存器的位数称为机械字长, 人人说的无标记数实在就是不辨别正负号的数,换句话说,就是没负数,满是正数,人人晓得,盘算机中的数是以0-1存储的, 假如我们的寄存器16位, 无标记数示意的局限就是0~65535 (2^64=65536), 有标记就是分正负数,总数65536就被分红两半,一半正数,平常负数,局限就是 -32768~32767
有标记数
有标记数,就是正负数同时存在, 人们固然能辨别开整正负数,盘算机怎样辨别呢?
前面说了,盘算机只熟悉01如许的数,因而人们划定 0示意正数, 1示意负数, 因而如许标记就被数字化了, 而且划定将其放在实在值前面, 因而有标记数就诞生了
如上图,依据盘算机存数数据的特征将标记数字化, 数字化后的编码体式格局获得的效果称为机械数, 将带有+-标记的数字称为真值
既然如今将有标记数数字化后,新的题目来了,当这些机械数之间须要举行运算时, 标记位怎样办? 标记位可否列入机械数之间的运算呢? 假如说,须要列入运算又须要哪些处置惩罚才消弭标记位对盘算效果的影响呢? 这一连串题目就引出了标记位和数值位所组成的编码: 原码 , 补码 , 反码 , 移码
实在在进修的历程当中该一向问自身,自身在干什么??? 就比方如今,我在前面也许说了说盘算机是怎样示意数字的,因而熟悉了机械码,机械码之间须要举行运算于为了设想出使机械码运算的体式格局,人们对机械码举行差别的变形编码,获得了,原码 , 补码, 反码 , 移码等, 下面看一下这几种编码的由来,以及他们对完成机械码的可盘算的孝敬
原码
原码是机械码最简朴的一种变形,一样的它的标记位0示意正数,1示意负数。 数值位就是真值的绝对值
人们为了誊写轻易已辨别小数和整数,在标记位和数值位之间运用逗号分开
整数的原码
举个例子:
x= +1110, 那末它的原码就是 0,1110
x= -1110, 原码=1,1110
小数的原码
举个例子
x= 0.1101 , 那末它的原码就是 0.1101
x= -0.1101, 原码=1 - (-0.1101) = 1.1101
看上面的原码盘算体式格局,明显机械码很轻易就转成原码,然则想一想假如用原码举行数值运算的话就会带来许多贫苦,我们得先推断两个机械数绝对值的大小然后用大的减去小的,终究的标记再依据绝对值大的算, 而且我们须要设想两套运算流程,一套给加法用,一套给减法用, 然则先辈们很伶俐,因为人们找到了一种体式格局,找到了一个正数去替代本来减数位置的负数,相似像下面如许,完成了在盘算机中仅仅设想一套加法器就完成加减法的运算
5-3=2
5+(-3)=2
上述要领的完成就依赖于下面的补码
补码
补码的观点和补数的观点很像, 比方如今时钟六点了,我们想让它指向三点,因而我们能够往反转3(6-3=3)圈时针能回退到3点,也能够往前转9圈(6+9=15),能够前进到三点, 对时钟来讲往顺时针照样逆时针的历程不一样,然则对我们来讲效果是一样的,都是三点了
这个历程就相似于,找到一个正数,让这个正数替代负数去列入运算,运用加法运算器也能获得正确的效果
时钟扭转一圈12小时,在这12小时中是不被显现且自动丧失的,也就是说 15-3=3 点, 因而我们能够说,实在对时钟来讲, -3 +9 的作用实际上是一致的,效果都是三点, 在数学上我们将12称为模 ,写成mod 12 , 我们管9 称为是 -3以12为模的补数
因而我们得知,只需我们肯定了模,我们就可以求出这个数对这个模的职位雷同的补数,或许说当我们想将已知的负数转换成能够替代他的正数的话,借助模就可以够完成
怎样应用模求补数呢?
- 正数的补数是它自身
- 负数能够用它的正补数等价替代
- 负数的补数= 模+负数自身
怎样举行求模示例:
-3 全即是 +7 (mod10)
+7 全即是 +7 (mod10)
-3 全即是 +97 (mod100)
-1011 全即是 +0101 (mod2^4)
2^4=1 0 0 0 0
- 1 0 1 1
---------------
0 1 0 1
+0101 全即是 +0101 (mod2^4)
小数的mod = 2
+0.1001 全即是 +0.1001 (mod2)
-0.1001 全即是 +1.0111 (mod2)
1 0.0 0 0 0
- 0.1 0 0 1
--------------
1.0 1 1 1
求补码的公式
求负数补数的示例
实在人人能够看一下,对负数的公式来讲,公式中的n就是负数的位数, -1101 一共四位, n=4, 然则取的是n+1位, 换句话说是用一个比原负数多两位的数加上这个负数, 多出来一个标记位, 末了的效果中别忘了用 逗号分开标记位和数值位, 固然这是为了轻易我们自身看,让人们一眼看去晓得最最先的1是个标记位,背面的数才是 想求的补数效果
小数求补码的公式
举个例子: 求 -0.0110 的补码
别的, +0 -0的补码都是 0
从上面的议论我们晓得,之所以想引入补码是为了消弭减法运算,行将一个负数转换成它的正数补码,然则依据补码的定义,人人能够看到上面的两个例子,在发生补码的历程当中又涌现了减法运算,怎样办呢?
因而我们如许求补码: 先求原码, 然后变更这个原码获得补码, 怎样变更呢? 就是将除了 标记位的原码其它为取反 以后再加1
举个例子: 上面的就用 -1101 来讲, 以下:
因而看到这里我们完整晓得了,只为盘算机设想一个加法器是完整ok的,下文会引见怎样运算
反码
经由过程上面的运算我们晓得下面的运算划定规矩
原码(标记位,数值位) => 除标记位外其他位取反 = 反码
反码+1 = 补码
补码-1 = 反码
由此可知,实在这个反码就是原码和补码两边转换时的中间状态
小结
- 原码,反码,补码的最高位都是标记位, 标记位和数值位之间运用.或许逗号分开(小数用点, 整数用逗号)
- 真值为整数时, 原码,反码,补码的示意情势是雷同的
- 虽然真值为负数时,原码.反码补码各不雷同,然则最高位的标记为都是1, 而且原码求反+1=补码 , 原码每位求反=反码
移码
真值转换成补码后,因为标记位和数值位是一同举行编码的,因而人们很难分清补码之间的大小
就像下面如许
十进制的21 对应二进制为+10101 补码为 0,10101
十进制的-21 对应二进制为-10101 补码为 1,01011
十进制的31 对应二进制为 +11111 补码为 0,11111
十进制的-31 对应二进制为-11111 补码为 1,00001
直观上看他们的大小是 101011>010101 100001>011111 而实际上恰恰相反
因而我们如许, 在每个真值的基础上加上一个2^n , 状况就发生了变化
+10101 加上2^5 得 110101
-10101 加上2^5 得 001011
+11111 加上2^5 得 111111
-11111 加上2^5 得 000001
如许的话不须要借助补码,六位代码自身就可以看到出真值的大小
更进一步,经由过程视察能够发明,实在一个数的补码和移码之间就差一个标记位,换句话说,假如我们将补码的标记位从0换为1,或许从1换成0获得的就是它的移码, 在这基础上比较大小获得的效果是正确的
别的正负零的移码的一样的
移位运算
盘算机中的机械数的字长往往是牢固的,当机械数左移n位或许是又移n位时,势必会却是别的一边涌现空位,那末在涌现空位的位置究竟是补充1照样添补0呢? 这取决于机械数是有标记照样无标记,其中有标记的机械数采用的位移称为算数位移,无标记的唯一称为逻辑位移
算数位移的移位划定规矩
真值 | 码制 | 补填代码 |
---|---|---|
正数 | 原码,补码,反码 | 0 |
负数 | 原码 | 0 |
负数 | 原码 | 左移添0 |
负数 | 补码 | 右移添1 |
负数 | 反码 | 1 |
无论是正数照样负数,移位后的标记位都是稳定的
举几个例子
机械数 十进制
移位前 : 0,0011010 +26
左移1位: 0,0110100 +52
右移1位: 0,0001101 +13
左移一名,除标记位外本来的最高位被移走了,右侧空出的1位用0补全,然则高位丧失了实在获得的就是毛病的效果,然则这个毛病的效果恰好是原值的2倍,而且唯一运算速率还快,因而许多框架的底层都喜爱运用这个位移运算的特征
每次右移时,最右侧的数就会丧失,精度收到影响
左移一名相当于乘以2,右移1位相当于除以2
逻辑位移的移位划定规矩
逻辑左移,高位丧失,低位填0, 逻辑右移,低位丧失,高位补0
加法与减法运算
回到一最先话题,盘算机的运算要领,前面经由过程补码的引见我们晓得了只设想一套加法器实际上是可行的,下面详细看一下是怎样举行运算的
即 A-B = A + (-B)
补码的加法公式
整数: [A]补 + [B]补 = [A+B]补 (mod 2^n+1)
小数: [A]补 + [B]补 = [A+B]补 (mod 2)
关于减法来讲
整数: [A-B]补 = [A]+[-B]补 (mod 2^n+1)
小数: [A-B]补 = [A]+[-B]补 (mod 2)
末了看一个例子: 看看盘算机怎样将减法转换成加法并照顾标记位运转得出正确效果
假定机械8位(含一名标记位),若A=+15 B=+24, 让我们求 [A-B]补 ,并复原真值
A=+15 = +0001111 (算上+号一共八位)
b=+24 = +0011000 (算上+号一共八位)
A和B都是整数,所以他们的补码就是原码自身:
[A]补 = 0,0001111
[B]补 = 0,0011000
[-B]原码 = 1,0011000
[-B]反码 = 1,1100111 ( 除标记位取反获得反码:)
[-B]补 = 1,1101000 (由反码+1获得)
[A-B]补 = [A]补 + [-B]补
= 0,0001111 + 1,1101000
= 1,1110111
那末 A-B = 啥呢? 反着换回去
1,1110111
1,1110110 (末位减1再取反)
1,0001001 = -0001001 = -9