問題描述:
在計算機中,由於處理器位寬限制,只能處理有限精度的十進制整數加減法,比如在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);
}
}
以上僅是我個人的一點想法,方法可能不是很好,希望大家指導!