问题描述:
在计算机中,由于处理器位宽限制,只能处理有限精度的十进制整数加减法,比如在32位宽处理器计算机中,
参与运算的操作数和结果必须在-231~231-1之间。如果需要进行更大范围的十进制整数加法,需要使用特殊
的方式实现,比如使用字符串保存操作数和结果,采取逐位运算的方式。
如下:
9876543210 + 1234567890 = ?
让字符串 num1="9876543210",字符串 num2="1234567890",结果保存在字符串 result = "11111111100"。
-9876543210 + (-1234567890) = ?
让字符串 num1="-9876543210",字符串 num2="-1234567890",结果保存在字符串 result = "-11111111100"。
题目:要求编程实现上述高精度的十进制加法。
我的思路是:先将每个字符串除符号位之外的所有数字位转换成整数,然后按照右对齐的方式,暂时不考虑进位或借位,进行加减法运算,之后再考虑每一位是否需要进位或借位,更新每一位的值,最后再将这些数值转换成字符,存入相应的数组。
下面是参考代码:
#include <iostream>
#include <stdlib.h>
#include <string>
#define MAX 15
using namespace std;
void add(const char *num1,const char *num2,char *result);
int main()
{
char num1[]="-9876543210";
char num2[]="-1234567890";
char res[MAX]="";
add(num1,num2,res);
return 0;
}
void add(const char *num1,const char *num2,char *result)
{
if (num1==NULL || num2==NULL)
{
return;
}
if ((num1[0]=='-'&& num1[1]=='0') || num1[0]=='0' || (num2[0]=='-'&& num2[1]=='0') || num2[0]=='0')
{
return;
}
const char *n1=NULL;
const char *n2=NULL;
char *p=result;
int len1=strlen(num1);
int len2=strlen(num2);
int sum[MAX+1]={0};
int x[MAX]={0};
int y[MAX]={0};
int i=0,j=0;
//不考虑符号位,哪个字符串长,就将哪个赋给n1,将来转换成整数时存放在x[]中
if((*num1=='-' && *num2=='-') || (*num1!='-' && *num2!='-'))
{
if (len1>=len2)
{
n1=num1;
n2=num2;
}
else
{
n1=num2;
n2=num1;
}
}
else if(*num1=='-' && *num2!='-')
{
if (len1-1>=len2)
{
n1=num1;
n2=num2;
}
else
{
n1=num2;
n2=num1;
}
}
else
{
if (len1>=len2-1)
{
n1=num1;
n2=num2;
}
else
{
n1=num2;
n2=num1;
}
}
//把第一个数的每一位转换成数字,保存在数组中
if (n1[0]!='-')
{
for (i=len1-1;i>=0;i--)
{
x[i]=(n1[i]-'0');
//cout <<x[i]<<" ";
}
}
else
{
for (i=len1-1;i>0;i--)
{
x[i]=n1[i]-'0';
//cout <<x[i]<<" ";
}
}
//把第二个数的每一位转换成数字,保存在数组中
if (*n2!='-')
{
for (j=len2-1;j>=0;j--)
{
y[j]=n2[j]-'0';
//cout <<y[j]<<" ";
}
}
else
{
for (j=len2-1;j>0;j--)
{
y[j]=n2[j]-'0';
//cout <<y[j]<<" ";
}
}
//cout<<endl;
int takeover=0;//进位标志符
int takedown=0;//借位标志符
int k=0;
//1:两个数都为正数
if (*n1!='-' && *n2!='-')
{
//先不考虑进位,求每一位对应的和
for(i=len1-1,j=len2-1;i>=0;i--,j--)
{
if (j>=0)
{
sum[k]=x[i]+y[j];
//cout <<sum[k] <<" ";
}
else
{
sum[k]=x[i];
}
k++;
}
//cout<<endl;
//计算进位,修改相应位的值
for (i=0;i<MAX;i++)
{
if (sum[i]>=10)
{
sum[i]=sum[i]%10;
takeover=1;
sum[i+1]+=takeover;
}
}
//把每一位转换成字符型
if (sum[len1]==0)
{
for (i=0;i<len1;i++)
{
p[len1-1-i]=sum[i]+'0';
}
}
else
{
for (i=0;i<=len1;i++)
{
p[len1-i]=sum[i]+'0';
}
}
printf("%s\n",p);
}
//2:两个数都为负数
else if (*n1=='-' && *n2=='-')
{
//先不考虑进位,求每一位对应的和
for(i=len1-1,j=len2-1;i>0;i--,j--)
{
if (j>0)
{
sum[k]=x[i]+y[j];
//cout <<sum[k] <<" ";
}
else
{
sum[k]=x[i];
}
k++;
}
//cout<<endl;
//计算进位,修改相应位的值
for (i=0;i<MAX;i++)
{
if (sum[i]>=10)
{
sum[i]=sum[i]%10;
takeover=1;
sum[i+1]+=takeover;
}
}
//把每一位转换成字符型
if (sum[len1-1]==0)
{
for (i=0;i<len1-1;i++)
{
p[len1-1-i]=sum[i]+'0';
}
}
else
{
for (i=0;i<len1;i++)
{
p[len1-i]=sum[i]+'0';
}
}
p[0]='-';
printf("%s\n",p);
}
//3:较长的数为正数,较短的数为负数
else if (*n1!='-' && *n2=='-')
{
//不考虑借位,计算每一位对应的差
for(i=len1-1,j=len2-1;i>=0;i--,j--)
{
if (j>0)
{
sum[k]=x[i]-y[j];
}
else
{
sum[k]=x[i];
}
k++;
}
//根据每一位的值,考虑借位,更新数值
for (i=0;i<len1-1;i++)
{
if (sum[i]<0)
{
sum[i]=sum[i]+10;
takedown=1;
sum[i+1]-=takedown;
}
}
//把每一位转换成字符型
if (sum[len1-1]>0)
{
for (i=0;i<len1;i++)
{
p[len1-1-i]=sum[i]+'0';
}
}
else if(sum[len1-1]==0)
{
for (i=0;i<len1-1;i++)
{
p[len1-2-i]=sum[i]+'0';
}
}
else
{
for (i=0;i<len1-1;i++)
{
sum[i]=10-sum[i];
takedown=1;
sum[i+1]+=takedown;
}
if(sum[i]==0)
{
for(i=0;i<len1-1;i++)
{
p[len1-1-i]=sum[i]+'0';
}
}
else if (sum[i]<0)
{
sum[i]=-sum[i];
for(i=0;i<=len1-1;i++)
{
p[len1-i]=sum[i]+'0';
}
}
p[0]='-';
}
printf("%s\n",p);
}
//4:较长的数为负数,较短的数为正数
else if (*n1=='-' && *n2!='-')
{
//不考虑借位,计算每一位对应的差
for(i=len1-1,j=len2-1;i>0;i--,j--)
{
if (j>=0)
{
sum[k]=x[i]-y[j];
}
else
{
sum[k]=x[i];
}
k++;
}
//根据每一位的值,考虑借位,更新数值
for (i=0;i<len1-2;i++)
{
if (sum[i]<0)
{
sum[i]=sum[i]+10;
takedown=1;
sum[i+1]-=takedown;
}
}
//把每一位转换成字符型
if (sum[len1-2]>0)
{
for (i=0;i<len1-1;i++)
{
p[len1-1-i]=sum[i]+'0';
}
p[0]='-';
}
else if(sum[len1-2]==0)
{
for (i=0;i<len1-2;i++)
{
p[len1-2-i]=sum[i]+'0';
}
p[0]='-';
}
else
{
for (i=0;i<len1-2;i++)
{
sum[i]=10-sum[i];
takedown=1;
sum[i+1]+=takedown;
}
if(sum[i]==0)
{
for(i=0;i<len1-1;i++)
{
p[len1-2-i]=sum[i]+'0';
}
p[0]='-';
}
else if (sum[i]<0)
{
sum[i]=-sum[i];
for(i=0;i<=len1-2;i++)
{
p[len1-2-i]=sum[i]+'0';
}
}
}
printf("%s\n",p);
}
}
以上仅是我个人的一点想法,方法可能不是很好,希望大家指导!