二进制是如何将加减乘除变换为加法实现的?加法是如何由逻辑运算与、或、异或来实现的?
关注者
151
被浏览
10205
查看全部 13 个回答
匿名用户
5分钟教会你古中国人古埃及人和计算机如何用二进制做乘除法 。 有空整理
找的“
1.乘法
由于计算机中,所有数值都是用2的N次方来表示的:2^n0+2^n1+2^n2+2^n3+2^n4.....
因此x*y,(x)*(2^n0+2^n1+2^n2+2^n3+2^n4)=(x*2^n0)+(x*2^n1)+(x*2^n2)+(x*2^n3)+(x*2^n4)+......即(x左移n0)+(x左移n1)+(x左移n2)+(x左移n3)+(x左移n4)+......
用15(x)*13(y)来举例,15*13 为1111*1101
a.首先y的最低位为1(2^0),x左移0位得到1111
b.然后y的最低第二位为0,没有2^1存在,因此本次无运算(结果可以看作为0)
c.然后y的最低第三位为1(2^2),x左移2位得到111100
d.然后y的最低第四位为1(2^3),x左移3位得到1111000
e.把a、b、c、d的结果相加1111+0+111100+1111000=11000011(195),该结果就是乘法的结果
特别的,x*y中,如果y是2的N次方,因此相当于x右移N位。
2.除法(加减交替法)
x/y其实就是,x不断减y的过程。小学时候学的长长除法就是这个原理。
用二进制的除法x/y,比十进制容易写,商不是0即是1,而且如果除数大于除数的1倍,商就是标记在另一个位上面了
二进制除法x/y=0.1001/0.1011手工计算如下
0.11
_______
0.1001/0.1001
10010(后面补0)
-1011
------
111(余数)
1110(后面补0)
-1011
--------
1(余数)
设ri表示第i次运算后所得的余数,则:
若ri>0,则商1,余数和商左移1位,再减去除数,即ri+1=2ri-y
若ri<0,则商0,余数和商左移1位,再加上除数,即ri+1=2ri+y
用85/6来举例,85/6=1010101/110
a.101(0101)左移1位到第3位都小于110,因此商=000
b.1010(101)左移四位是1010,比110大,商=0001,余数=1010-110=100(101)
c.余数100(101)左移一位是1001,比110大,商=00011,余数=1001-110=11(01)
d.余数11(01)左移一位是110,等于110,商=000111,余数=0(1)
e.余数0(1)左移一位是01,小于110,商=0001110,余数=01
因此85/6=1010101/110=0001110,即14,余数为最后的余数1
”
编辑于 2015-11-09
更多回答
知乎用户
加法是由基本门电路实现的
这个是全加器
其实基本都是数学知识
努力填坑中
半加器(英语:half adder)电路是指对两个输入数据位相加,输出一个结果位和进位,没有进位输入的加法器电路。 是实现两个一位二进制数的加法运算电路。
我们只需要一个异或门、一个与门即可实现。
全加器英语名称为full-adder,是用门电路实现两个二进制数相加并求出和的组合线路,称为一位全加器。一位全加器可以处理低位进位,并输出本位加法进位。多个一位全加器进行级联可以得到多位全加器。
我看的是《计算概论A》,感觉这个课程不错,我贴个课程链接https://www.coursera.org/course/pkuic
在计算机基础知识部分,我们将为大家解答一些与计算机程序设计相关的基础问题,例如,“计算机为什么能够进行计算?”,“计算机程序在计算机中是如何运行的?”,“计算机的发展规律是什么?”,“下一代的计算机将会是什么样子?”等等。我们希望通过对这些问题的解答,达到两个目的:A 培养起大家对计算机科学的兴趣;B 帮助大家建立起学习计算机科学所需要的“背景知识框架”。
本课程的内容针对“信息科学技术”专业的一年级本科生而设,我们不要求也不假设选课学生有任何信息科学技术相关专业的知识背景,也不要求有任何的程序设计知识背景。
编辑于 2015-11-09
早乙女瑞穂
学化学的医科毕业的程序猿
/***大家快闪开,我要装B了***/
乘除法已经更新了算法,浮点数计算下次再写……
楼上
@李震
的加法器其实已经回答了大半的问题了。
对于一般的计算机来说,有两种运算,一种叫做“整数运算”,另一种叫做“浮点小数运算”(某些特殊用途的单片机还有“固定小数点小数运算”)
【整数运算】
整数运算的基础就是加法和位移。这两种运算的组合囊括了五种基本的计算(加,减,乘,除,求余)
ps:除了加减法和位移操作之外,其他算法基本都是通过汇编来实现的。能用电路直接实现的计算只有(与或非和它们的衍生,例如加法,异或)
在介绍运算方法之前,首先需要了解以下的概念从而了解计算机记录整数的方法。
比特(bit):包含电流通/断信息的一个单位。又被称为“位”。一个“位”能表示二进制数的一个位。
字节(byte):由8个比特组成的单位,一个字节共能表示2^8=256个数。
补数:2个数A,B相加等于C,那么就说A是B的C补数。例如2是8的10补数。
为了方便描述计算机处理的二进制数据,人们也会用8进制和16进制来书写2进制数。记住0-15所对应的2进数和16进数的写法对计算机等级考试很有帮助。
例如,对于一个8位整数:
10进制:10
2进制:0000 1010
8进制:0012(3位的2进制数和1位的8进数等价)
16进制:0A(4位2进数和1位16进数等价)
一个8位(无符号)整数能表示的范围是“0~255”,共256个数。
加法:
加法运算就是将两个数通过加法器进行相加和进位。加法器的原理这里就不赘述了。
例如,对于2个8位整数“10”和“15”
0000 1010 +0000 1111 =0001 1001
0001对应16进数“1”,1001对应16进数“9”,于是直接答案可以写作16进数的“19”,也就是16+9=25。
再例如,对于2个8位(无符号)整数“3”和“254”,有
0000 0011+1111 1110这样得到的结果理应是“10000 0001”。但是,因为限定了“8位整数”这个条件,所以结果第九位的1就被计算机吞掉了。于是算出的最终结果是0000 0001。也就是“1”。
减法:为了减少计算机设计的复杂程度,工程师们人为规定了一个2进数的2补数为负数。同时规定一个整数的最上位的比特表示正负号(正数最上位为0,负数为1)。
因为最上位挪去表示正负号了,所以8位有符号整数的表示范围是“-128~127”,共256个数(因为0只有一个而且算正数,所以负数比正数多一个)
2补数的计算方法:
一个2进整数的所有比特全部翻转然后加上“1”。
例如:10进数“1”对应的8位有符号整数就是0000 0001而“-1”就是全部翻转后的1111 1110再加“1”得到1111 1111。这两个数相加得到“1 0000 0000”。因为是8位数,第九位被吃掉,于是得到“0”。
再举例:计算10进数“15-10”
首先,10的2进是0000 1010,-10就是
翻转后的1111 0101加1,1111 0110。
于是计算:
0000 1111(15)+1111 0110(-10)
得到“10000 0101”,去掉第9位得到“0000 0101”也就是“5”。
(文章最后我提供了一个方便的转换补数的工具“比特转换器”)
再举例:计算“15-16”
0000 1111 +1111 0000 = 1111 1111
“1111 1111”因为最上位是1,是负数,于是翻转后加1得到“0000 0001”,为“-1”。
乘除法:乘除法不仅需要加法和位移(关于实现位移的电路,请百度:桶式位移器),还需要寄存器记录下计算过程中的结果。一般情况下不会以纯电路来实现,而是结合电路和汇编代码来实现。当然,对于流行的单片机,例如51系列,atmega(arduino的cpu)系列,它们都有一系列的指令集来简化代码的复杂程度。可以说就是把这些个汇编算法写成语法糖方便嵌入式程序猿使用。
乘法:
对于10进数来说,将有效数字向左右位移能造成扩大/缩小10倍的效果。
10右移一位得到1,缩小10倍;左移一位得到100,扩大10倍。
同理,对于2进数来说,左右移能够扩大/缩小2倍。
0000 1010(10)右移一位得到0000 0101(5);左移一位得到0001 0100(16进数“14”,16+4=20)。
单靠位移只能变化偶数倍,结合加法便能变化奇数倍。
计算“10*5”(包含汇编算法,写的不好,还请大家包涵)
首先,寄存器中寄存初始的乘数10和5。
我们记做寄存器A和寄存器B。然后比较2个值的大小,发现A的值不小于B。
这时将寄存器A的值复制到寄存器C中,于是寄存器A和C的值都是0000 1010 。
因为寄存器B的值为0000 0101,大于0000 0010(2)。于是便将寄存器C的值向
左移一位后得到0001 0100(20),同时寄存器B减去0000 0010(2)得到0000 0011(3),依旧大于0000 0010(2)。
于是继续左移寄存器C的值一位,得到0010 1000(2*16+8=40),同时寄存器B继续减0000 0010(2)得到0000 0001(1),小于2大于0。
这时将寄存器C的值加上寄存器A的值得到0011 0010(3*16+2=50),同时寄存器B减去1得到0,算法结束,输出寄存器C的值0011 0010(50)作为结果。
除法和求余:
除法和求余比较复杂,而且是成对出现的。
例如“10/3”(这个汇编算法有待优化)
将被除数赋值给寄存器A,除数赋值给寄存器B、C,同时将寄存器D清零。
此时寄存器状态为
A:0000 1010(10)
B:0000 0011(3)
C:0000 0011(3)
D:0000 0000(0)
此时C的值不大于A,D的值增加1为0000 0001,将C加上B得到0000 0110(6),不大于A,将此值赋与C,
此时寄存器状态为
A:0000 1010(10)
B:0000 0011(3)
C:0000 0110(6)
D:0000 0001(1)
此时C不大于A,D的值增加1,为0000 0010(2)。继续将B和C相加得到0000 1001(9),不大于A,将值赋给C。
此时寄存器状态为
A:0000 1010(10)
B:0000 0011(3)
C:0000 1001(9)
D:0000 0010(2)
此时C不大于A,D的值增加1,为0000 0011(3)。继续将B和C相加得到0000 1100(12),大于A,舍弃。输出D的值“3”作为商输出。同时将A(10)的值减去C(9)的值得到0000 0001(1)作为余数输出。
PS:顺便夹带点私货:比特转换器
专门为理解计算机的整数运算而设计的安卓app
https://play.google.com/store/apps/details?id=com.mycompany.posiconv&hl=cn
【小数的运算】
小数运算利用的是浮点小数运算单元进行计算的,和整数运算法则完全不同。
(今天太累了,以后再写……)