题目: 有两个各存放在数组A和B中的n位二进制整数,考虑它们的相加问题。两个整数的和以二进制形式存放在具有(n+1)个元素的数组C中。请给出这个问题的形式化描述,并写出伪代码。
分析:二进制整数的编码,此处考虑原码和补码,原码可以通过转化成补码来运算,这也体现了补码在运算上的优势。
实质为模拟计算机二进制补码的加法
计算机中采用补码进行加法运算,并约定存储单元和运算寄存器中的数都采用补码表示,数据运算结果也用补码表示。
定点小数补码加法的运算公式为
[x]补+[y]补=[x+y]补 (mod 2)
推广到定点整数后得出定点整数补码加法的运算公式为:
[x]补+[y]补=[x+y]补 (mod 2n+1)
简单证明该公式:
根据补码的定义有:[x]补 = 2n-x (n为字长-1)
那么, [x]补+[y]补 = 2n-x + 2n-y = 2n+1 –(x+y) = [x+y]补 (mod 2n+1)
简单用语言描述,即将补码的符号位带入运算,按位对应相加,有进位则进。并舍弃符号位的进位(如果有进位的话)。
代码很简单
void sum(int* a, int* b, int len, int* c)
{
int carry = 0;
int temp, i;
for(i=len-1; i>=0; i--)
{
temp = a[i] + b[i] + carry;
if(temp >= 2)
{
carry = 1;
c[i+1] = temp - 2;
}
else
{
carry = 0;
c[i+1] = temp;
}
}
c[0] = (a[0] + b[0] + carry) % 2;
}
引申:
1、补码的实质。
以时钟为例,3点可表示为 时钟从12点方向顺时针转90°,也可表示为时钟从12点方向逆时针转270°。
即3 = 0 + 3, 且 3 = 12 - 9, 那么这样一来0-12的任意数字都有两种表示方式,x 和 12-(12-x);
对应到二进制的补码,它和时钟的相同点在于,值溢出后会产生循环。如12点后会变回1点周而复始,最大的正数溢出后会变成负数。
2、为什么使用补码
可以将符号带入运算,从而将减法转换成加法。
计算机内部只有加法器,而无减法器,加法器可以由简单的与非门组合而成,减法器的制作线路复杂,因而使用加法代替减法是必要的。