前言
??本文用C语言实现了大数加减法, 最多支持127位数加减(结果是127位) 不支持负数加减法, 不过可以做少许修改添加对负数的支持。其中减法部分用宏注释了之前的代码, 现在是优化后的代码。
友情链接
??整体源码及效果图见此: xin9912的NoteHub-大数加减法
加法部分
??加法部分两个数从低到高依次相加即可, 然后再从低到高处理进位。再处理结果即可, 代码如下:
int bigNumSum(char rst[],char a[],char b[],int numa,int numb)
{
int i,high,low;
char *pHigh = NULL,*pLow = NULL;
(numa < numb) ? ((high = numb) & (low = numa)) : ((high = numa) & (low = numb));
(numa < numb) ? ((pHigh = b) && (pLow = a)) : ((pHigh = a) && (pLow = b));
for(i = low;i > 0;i--)
{
rst[high] += (pLow[i - 1] + pHigh[high - 1] - '0');
high--;
if(rst[high + 1] > '9')
{
rst[high + 1] -= 10;
rst[high]++;
}
}
if(high == 1)
goto last;
for(i = high;i != 0;i--)
{
rst[i] += pHigh[i - 1];
if(rst[i] > '9')
{
rst[i] -= 10;
rst[i - 1]++;
}
}
last:
return (rst[0] == 1) ? (!(rst[0] = '1')) : 1;
}
??这里我们需要以位数的最大值为结果位数, 但是相加次数需要以位数少者为标准。考虑最高位可能进1, 因此这里是把rst[0]作为进位预备位。如果进位了偏移量则是0, 否则将会是1。你可以尝试 99999 + 1
减法部分
??减法部分需要考虑被减数与减数之间的大小, 才能决定怎么运算。因此这里是先比较大小以找出较大者, 然后再做运算时。同样也是从低到高进行运算, 然后处理结果。代码如下:
int bigNumSub(char rst[],char a[],char b[],int numa,int numb)
{
int i,j,high,low;
char *pHigh = NULL,*pLow = NULL;
if(numa != numb)
{
(numa < numb) ? ((high = numb) & (low = numa)) : ((high = numa) & (low = numb));
(numa < numb) ? ((pHigh = b) && (pLow = a)) : ((pHigh = a) && (pLow = b));
}
else
{
(strcmp(a,b) < 0) ? ((high = numb) & (low = numa)) : ((high = numa) & (low = numb));
(strcmp(a,b) < 0) ? ((pHigh = b) && (pLow = a)) : ((pHigh = a) && (pLow = b));
}
j = high;
for(i = low;i > 0;i--)
{
rst[j] = pHigh[j - 1] + '0' - pLow[i - 1];
j--;
}
if(j > 0)
{
for(i = j;i > 0;i--)
rst[i] = pHigh[i - 1];
}
for(i = high;i > 1;i--)
{
if(rst[i] < '0')
{
rst[i] += 10;
rst[i - 1]--;
}
}
for(j = 1;j <= high;j++)
{
if(rst[j] == '0')
continue;
else
break;
}
if(numa < numb || (numa == numb && strcmp(a,b) < 0))
{
j--;
rst[j] = '-';
}
return j;
}
??这里需要注意如果两个数位数不一样, 那么大小则很明显了。两者位数一样则需要使用strcmp函数获取结果(一直比较直到两个字符串某个字符不等), 这样确定了两个数的大小, 再依次做运算。j > 0 则是表明两个数位数不一样, 然后寻找偏移量, 确定符号。
|