本程序只实现正数的大数减法,不考虑负数。
if (Cmp(t, y) <= 0)
Mov_Long(0, t);//该语句是将数组t赋值为t[33]={1,0},赋值为0
假设是z=x-y,若x<y,那么设z=0.
while (t[t[0]] == 0)
t[0]--;//这里的t是中间值。x数组赋值给t数组
在程序中,我设定数组的第0位为大数的长度,计算所得z[0]的长度应该是等于x[0],如果x[x[0]]=y[y[0]],计算所得z[0]的长度应该是等于x[0]-1,若x[x[0]-1]=y[y[0]-1],计算所得z[0]的长度应该是等于x[0]-2,以此类推
举列子:x[33]={5, 0xD69ECF25, 0xE56EE19C, 0x18EA8BEE, 0x49F2934B, 0xF58EC744}
y[33]={5,0x7C66DDDD, 0xE8C4E481, 0x09DC3280, 0x11E40869, 0xF58EC744}
结果可以得z[0]=x[0]-1
若:
x[33]={5, 0xD69ECF25, 0xE56EE19C, 0x18EA8BEE, 0x49F2934B, 0xF58EC744}
y[33]={4,0x7C66DDDD, 0xE8C4E481, 0x09DC3280, 0x49F2934B, 0xF58EC744}
结果可以得z[0]=x[0]-2
```c
for (i = 1; i <= x[0]; i++)
{
if ((t[i] > y[i]) || ((t[i] == y[i]) && carry == 0))
{
t[i] = x[i] - y[i] - carry;
carry = 0;
}
else
{
num = 0x100000000 + t[i];
t[i] = (unsigned int)(num - carry - y[i]);
carry = 1;
}
减法最麻烦的事情要考虑借位的问题,如果x[i]<y[i],那么要向x[i+1]借一个1,x[i+1]要减1,所以大数减法考虑两种情况
第一种 x[i]>y[i] 或(x[i]=y[i], carry=0)
直接减 t[i] = x[i] - y[i] - carry;;
不需要借位 carry=0
否则
向后一位数组借1,就是0x100000000
t[i]=0x100000000+x[i]-y[i]-carry
carry=1
**最终程序如下图所示**
/****************************************************************************************************
大数相减
调用方式Sub(x,y,z)
返回值,z=x-y
*****************************************************************************************************/
void Sub_Big(unsigned int x[], unsigned int y[], unsigned int *z)
{
int i;
unsigned int t[MAX];
unsigned int carry = 0;
unsigned long long num = 0;
Init(t);
Mov_Big(x, t);
if (Cmp(t, y) <= 0)
Mov_Long(0, t);
else
{
for (i = 1; i <= x[0]; i++)
{
if ((t[i] > y[i]) || ((t[i] == y[i]) && carry == 0))
{
t[i] = x[i] - y[i] - carry;
carry = 0;
}
else
{
num = 0x100000000 + t[i];
t[i] = (unsigned int)(num - carry - y[i]);
carry = 1;
}
}
while (t[t[0]] == 0)
t[0]--;
}
Mov_Big(t, z);
}
程序运行结果是
这里数据用16进制数表示