机器中的加减法并不像我们实际生活中一样,带有正负号,比较容易运算,机器中只有0和1,那就需要一种算法来实现加减法运算。
首先,我们要明确目标是要进行带符号的数字(signed)进行加减法运算。
由于没有正负号,我们要采取一种措施来使某一位变为符号位,即最高位,如果是负数那么表示1,正数即为0,不再赘述。
下面来表示几个数字,如:(在此,用8位来表示一个数字,即1Byte)
1: 0000 0001
-1:1000 0001
0:0000 0000
每个数字有三种表示形式:(过余码不介绍)
1.原码
2.反码(正数反码和原码相同):原码最高位符号位不变,其余位取反
3.补码(正数补码和原码相同):原码最高位符号位不变,其余位取反加一
由于原码中最高位用来表示符号位,所以表示范围为-127~+127,包含正0和负0
而补码的表示范围为-128~+127
这就导致了-128无法由补码转为原码,-128的补码表示为:1000 0000
在计算中也可能产生溢出的情况,不过本文并未加以赘述。如127+127如果用补码运算并非254,因为原码表示范围有限,不过补码的意义就是对256进行同模运算,318和62对256是同模的,所以补码均为0011 1110,最高位溢出丢失。
计算机中加法实则是补码的加法,减法也有多种方法。
如:45+22->
0010 1101
+ 0001 0110
= 0100 0011->和为67的补码
如 54+(-73)->
0011 0110
+ 1110 1101
= 1001 1001 -> 和为-103的补码
减法也是同理:其实和加法相同,
(1)采用减法表即可:
- 01
0 0-1
1 10
如果产生-1则相应Carry Flag置1即可
或者
(2)采用加上一个负数的形式,具体如:
1111 0000 - 0000 1111 = 1111 0000 + (-0000 1111),再求出相应补码进行运算
(3)加上一个'最大值'
何为最大值呢?例如,我们在进行十进制减法时,经常采取Borrow的方法,即借位,借位就是加上一个9
如 253-176,计算的方法就是
999-176 = 823
253+823 = 1076
1076+1-1000 = 77
而当被减数小于减数时,如:176-253,为了避免借位,我们首先要从999中减去减数,
999-253 = 746
176+746 = 922
922 - 999 ?我们已经意识到了,减去最大的数一定是个非正数,所以我们交换
-(999 - 922)= -77
而在二进制中借位如何表示呢?
借用1111 1111一切问题迎刃而解,事实上,补码的意义就是在这种运算中得出的结论。一切步骤与十进制相似。
附上python中求补码和加法的代码(python初学者),并没有编写补码求原码的过程,即需要减一求反码:
#coding=gbk
#将对应数字转换为二进制
def orgin(num ):
if num >= 0:
dest_bin = ['0']
else:
dest_bin = ['1']
num = abs(num)
i = 64
while(i):
if( num/i ):
temp = ['1']
num -= i
else:
temp = ['0']
dest_bin = dest_bin + temp
i /= 2
return dest_bin
#转换为补码前要取反
def inverse( org_num ):
i = 1
while(i < len(org_num)):
if org_num[i] == '0':
org_num[i] = '1'
elif org_num[i] == '1':
org_num[i] = '0'
i += 1
return org_num
#进行补码的加法
def add_bin( num1, num2):
len1 = len(num1)
sum_num = ['0']*len1
carry_flag = 0
while(len1 >= 0):
len1 -= 1
sum = int(num1[len1]) + int(num2[len1]) + carry_flag
if sum == 0:
pass
elif sum == 1:
sum_num[len1] = '1'
carry_flage = 0
elif sum == 2:
carry_flag = 1
sum_num[len1] = '0'
elif sum == 3:
carry_flag = 1
sum_num[len1] = '0'
return sum_num
#转换相应的数字为补码
def tran( num ):
print '%d:' % num
if num == -128:
return ['1']+['0']*7
elif(num >= 0):
return orgin(num )
else:
str_temp = orgin(num )
str_temp = inverse(str_temp)
str_temp = add_bin(str_temp, ['0']*7+['1'])
return str_temp
def display( num):
for i in num:
print i,
print
if __name__ == '__main__':
display(tran(1))
display(tran(-127))
display(tran(-128))
display(tran(-127))
display(tran(88))
display(tran(0))