地址:http://www.cppblog.com/0and1/ | E-Mail:firenight@163.com | QQ:79688942 |
第一个思路没搞好,写的很烦琐……
#include <stdio.h>
#include <string.h>
#include <process.h>
#include <math.h>
#include <conio.h>
#define MAX 50000
void num_read(int *a)
{
int len,i,flag=0,err_msg;
char temp[MAX];
do
{
err_msg=0;
scanf("%s",&temp);
len=strlen(temp);
if (temp[0]=='-') flag=1;
for(i=len-flag;i>=1;i--)
{
if ((temp[len-i]-'0')<0||(temp[len-i]-'0')>9)
{
printf("你输入的第%d位不合法,请重新输入!!\n",len-i+1);
err_msg=1;
break;
}
else
a[i]=temp[len-i]-'0';
}
}
while (err_msg);
if (flag)
a[0]=-(len-1);
else
a[0]=len;
}

void num_print(int *a)
{
int i;
if (a[0]<0)
printf("-");
if (a[0]==0)
{
printf("0");
return;
}
for(i=abs(a[0]);i>=1;i--)
printf("%d",a[i]);
printf("\n");
}

void format_add(int *a)
{
int p;
for(p=1;p<a[0]||a[p]>=10;p++)
{
if (p>=a[0])
a[p+1]=0;
a[p+1]+=a[p]/10;
a[p]=a[p]%10;
}
if (p>=a[0])
a[0]=p;
}

void add(int *a,int *b,int *c)
{
int len,i;
if (a[0]<b[0]) len=a[0];
else len=b[0];
for(i=1;i<=len;i++)
c[i]=a[i]+b[i];
if (len<a[0])
{
for (;i<=a[0];i++)
c[i]=a[i];
c[0]=a[0];
}
else
{
for(;i<=b[0];i++)
c[i]=b[i];
c[0]=b[0];
}
format_add(c);
}

void format_sub(int *a)
{
int i;
for (i=1;i<=a[0];i++)
if (a[i]<0)
{
a[i]+=10;
a[i+1]-=1;
}
}

void sub_1(int *a,int *b,int *c)
{
int i;
for (i=1;i<=b[0];i++)
c[i]=a[i]-b[i];
if (a[0]!=b[0])
for (;i<=a[0];i++)
c[i]=a[i];

c[0]=a[0];
format_sub(c);
i=c[0];
while(c[i]==0)
i--;
c[0]=i;
return;
}


void sub(int *a,int *b,int *c)
{
int i,flag=0;
for (i=1;i<=a[0];i++)
if (a[i]!=b[i])
{
flag=1;
break;
}
if (flag==0)
{
c[0]=0;
return;
}
flag=0;
if (a[0]==b[0])
{
i=a[0];
while(i>0)
{
if (a[i]>b[i])
{
sub_1(a,b,c);
break;
}
if (a[i]<b[i])
{
flag=1;
sub_1(b,a,c);
break;
}
i--;
}
}
if (a[0]>b[0])
sub_1(a,b,c);
else
if (a[0]<b[0])
{
flag=1;
sub_1(b,a,c);
}
if (flag)
c[0]=-c[0];
else
c[0]=c[0];
}


void main()
{
int a[MAX],b[MAX],c[MAX];
while(true)
{
system("cls");
printf("\n**********************\n");
printf("\n");
printf(" 1.大数的加法 \n");
printf(" 2.大数的减法 \n");
printf(" 3.退出 \n");
printf("\n");
printf("**********************\n");
printf("\n请选择[1-3]:");
switch(getch())
{
case '1':
printf("\n");
printf("请输入大数A:");
num_read(a);
printf("请输入大数B:");
num_read(b);
if (a[0]<0 && b[0]<0) {a[0]=-a[0];b[0]=-b[0];add(a,b,c);c[0]=-c[0];a[0]=-a[0];b[0]=-b[0];}
if (a[0]>0 && b[0]<0) {b[0]=-b[0];sub(a,b,c);b[0]=-b[0];}
if (a[0]>0 && b[0]>0) {add(a,b,c);}
if (a[0]<0 && b[0]>0) {a[0]=-a[0];sub(b,a,c);a[0]=-a[0];}
printf("\n");
printf("A=");
num_print(a);
printf("B=");
num_print(b);
printf("C=A+B=");
num_print(c);
printf("\n要继续计算吗?(y/n)");
if (getch()=='n') return;
break;
case '2':
printf("\n\n");
printf("请输入大数A:");
num_read(a);
printf("请输入大数B:");
num_read(b);
if (a[0]<0 && b[0]<0) {a[0]=-a[0];b[0]=-b[0];sub(b,a,c);a[0]=-a[0];b[0]=-b[0];}
if (a[0]<0 && b[0]>0) {a[0]=-a[0];add(a,b,c);a[0]=-a[0];c[0]=-c[0];}
if (a[0]>0 && b[0]<0) {b[0]=-b[0];add(a,b,c);b[0]=-b[0];}
if (a[0]>0 && b[0]>0) sub(a,b,c);
printf("A=");
num_print(a);
printf("B=");
num_print(b);
printf("C=A-B=");
num_print(c);
printf("\n要继续计算吗?(y/n)");
if (getch()=='n') return;
break;
case '3':
return;
}
}
}
下面的比较简洁…………
#include <stdio.h>
#include <string.h>
#define MAX 10000
void num_read(int *a)
{
int len,i;
char temp[MAX];
scanf("%s",&temp);
len=strlen(temp);
for(i=len;i>=1;i--)
a[i]=temp[len-i]-'0';
a[0]=len;
}
int compare(int a[],int b[]) //比较大整数的大小
{
int i;
if (a[0]>b[0]) //比较a,b的位数确定返回值
return 1;
else
if (a[0]<b[0])
return -1;
else //位数相等时的比较
{
i=a[0];
while (a[i]==b[i]) //逐位比较
i--;
if (i==0)
return 0;
else
if (a[i]>b[i])
return 1;
else
return -1;
}
}
void bigplus(int a[],int b[],int c[]) //大整数加法
{
int i,len;
len=(a[0]>b[0]?a[0]:b[0]);
for(i=0;i<MAX;i++) //将数组清0
c[i]=0;
for (i=1;i<=len;i++) //计算每一位的值
{
c[i]+=(a[i]+b[i]);
if (c[i]>=10)
{
c[i]-=10; //大于10的取个位
c[i+1]++; //高位加1
}
}
if (c[i+1]>0)
len++;
c[0]=len; //c[0]保存结果数组实际长度
printf("Big integers add: ");
for (i=len;i>=1;i--)
printf("%d",c[i]);
printf("\n");
}
void bigsub(int a[],int b[],int c[]) //大整数减法
{
int i,len,com_flag;
len=(a[0]>b[0]?a[0]:b[0]);
for(i=0;i<MAX;i++) //将数组清0
c[i]=0;
com_flag=compare(a,b);
if (com_flag==0) //比较a,b大小
printf("Big integers sub=: 0");
else
if (com_flag>0)
for (i=1;i<=len;i++) //计算每一位的值
{
c[i]+=(a[i]-b[i]);
if (c[i]<0)
{
c[i]+=10; //小于0的原位加10
c[i+1]--; //高位减1
}
}
else
for (i=1;i<=len;i++) //计算每一位的值
{
c[i]+=(b[i]-a[i]);
if (c[i]<0)
{
c[i]+=10; //小于0原位加10
c[i+1]--; //高位减1
}
}
while (len>1 && c[len]==0) //去掉高位的0
len--;
c[0]=len;
printf("Big integers sub= ");
if (a[0]<b[0] || com_flag<0)
printf("-");
for(i=len;i>=1;i--)
printf("%d",c[i]);
printf("\n");
}


int main()
{
int a[MAX],b[MAX],c[MAX];
num_read(a);
num_read(b);
bigplus(a,b,c);
bigsub(a,b,c);
return 0;
}
觉得如果用文件记录结果,对无限位理论上成立,可没想好怎么实现…… 每个数组元素只记录一位数字,有点浪费,改成逢千进一可能提高空间利用率; 猜想模仿CPU的数值运算,应该更有效……
|