http://blog.csdn.net/blues1021/article/details/42849183
前言
- 虽然我们在编程语言中可以直接使用+-/,但是对某些要求不能用/的情况下,我们有必要了解一下计算机是怎样完成乘除法的。
- 首先,我们要明确一下计算机所能完成的最基本操作是:+(-)和左移右移。虽然ISA中一般都有MUL类指令,但是这些经过译码之后最终的元操作还是加法和移位指令。
乘法实现
- 我们知道在计算机中只有0和1,于是,就有了二进制计数,比如5 = 101. 抽象的说,任何一个数均可以表示为如下式子:
所以其他数乘以X,就变成了如下式子:
这就是计算机做乘法的原理。因为对于计算机而言,左移一位代表乘以2,右移一位代表除以2。所以,对于a乘以x而言,只是将a左移x为1的位并累加即可。
举例说明:5*3
- 3=0011(不用分解,计算机就是这么存储的)
- 3的第0位1,5左移0位仍为0;
- 3的第一位为1,5左移1位为5*2 = 10
- 然后将其累加,得到最后结果15.
代码如下:
//没有考虑传入数太大,导致溢出的情况。只做简单说明
int getBits(int num){
int numLen = 0;
while(num){
numLen++;
num = num>>1;
}
return numLen;
}
int getIndexBit(int num,int pos){//获取从右到左的第pos位置的值1/0
int index = 1<<pos;
if((num&index)>>pos)
return 1;
else
return 0;
}
int getBit(int num,int pos){//获取从右到左的第pos位置的值1/0
pos = pos-1;
return getIndexBit(num,pos);
}
int multi(int multi1,int multi2){
bool minus = false;
if(multi2<0){
minus = true;
multi2 = -multi2;
}
int length = getBits(multi2);
int index = 0;
int base = multi1;
int sum = 0;
while(index<length){
int val = getBit(multi2,index+1);
if(val)
sum+=(base<<index);
index++;
}
if(minus)
return -sum;
return sum;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
除法实现
除法实现起来要比乘法难一点,因此,让我们首先从人的角度来计算一下除法的实现。
人类计算除法
当我们在计算51/3=17,抛开9*9乘法表。
- 从被除数的最高位5开始,从0-9选一个数,使得5-i*3>=0且使5-(i+1)*3<0。我们选择了1. 余数为2.
- 将余数*10+1=21,继续从0-9中选一个数,使得21-3*i>=0且使5-(i+1)*3<0,我们选择了7.
- 由此,我们找到了答案17。
计算机计算除法
计算机计算除法的过程与人类计算的过程很类似,只是选择范围变成了0或1.
还以51/3为例说明(51:110011;3:11)
- 从第一位开始为1,小于11,结果位置0;余数为1
- 从第二位开始,余数*2+1=11,等于11,结果位置1,余数为0;
- 从第三、四位开始,余数*2+0=0<011,结果位置0,余数为0
- 从第5位开始,余数*2+1=1<11,结果置0,余数为1
- 从第6位开始,余数*2+1=11=11,结果置1,余数为0.
此时将结果位相连,恰好是10001(17)
乘法:被分解为左移累加。
除法:被分解为右移累减去,减法可以转换为加法。
浮点数的运算:
S x 2(^F) x M
浮点数是原码表示法,S符号位,F阶码 + 127, M尾数舍弃前面的1(如果F<=-127则小数最前是0也要舍弃,后面补上0,F会变为-126)。
F阶码用的表示法是偏移码(无符号整型表示,并不是书本说的移码,阶码加减运算的时候,应该用了寄存器处理,不是移码运算,因为位数都不够)。
浮点数加减:阶码对齐; 尾数加减,处理溢出,规格化即可。
浮点数乘除:无符号阶码偏移码加减运算,应该是转换为真值后,进行了有符号补码的运算,得到结果,而不是进行了移码的运算(因为移码运算得不到正确的结果);尾数进行整数乘除,得到结果处理溢出,规格化即可。
计算机乘法除法原理(原码)
(2013-12-04 16:09:30)
转载▼
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
由于计算机中,所有数值都是用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