高精度计算程序报告
问题描述
高精度计算
涉及知识点:数组、流程控制、函数等
要求:用整型数组表示10进制大整数(超过2^32的整数),数组的每个元素存储大整数的一位数字,实现大整数的加减法。
问题分析
高精度计算问题是由c语言中整型变量所占字节数有限导致的
因此,想定义更大的数的加减法,我们需要借助数组来储存一个较大的数,问题即在于:
1.将输入的数存入数组
2.对存储于数组中的数进行计算
3.输出存储于数组中的结果
数据类型
整型数组x[1001],y[1001],z[1001]分别用于存储输入的数1,输入的数2,输出结果;
整型变量xl,yl分别表示两个输入的数的位数;
字符变量c表示键入的字符,用于将输入数字转化为数组存储;
字符变量o表示运算符,用于记录运算符;
整型变量a,b分别表示x、y数组中最后一个输入的数字的序数;
整型变量sum表示在某一位计算中加和的得到的结果;
整型变量i,j均为计数符;
处理方法设计
根据数字的十进制基本定义进行计算;
因为scanf函数无法区分数字符和运算符,所以我采用单个字符的方式录入数字,并通过isdigit函数来区分数字符与运算符,并用o来记录运算符,这样,我们计算所需的信息就都录入了。
根据加法的基本定义,对每一位的数字进行加和,大于等于10时进1,小于0时退1,其原理即是科学计数法,将一个大数字拆分为每一位进行运算,如若遇到负数时,最终结果将记录为-1abcdefg的形式,其代表数字为-10000000+abcdefg,我们只需对负数进行整理即可;
对于整数结果,我们直接输出;
对于0结果,我们也直接输出;
对于负数结果,我们对每一位进行计算,正数位退1成为负数,最后输出;
最终即可得到计算结果。
上述程序可适用于加减运算,经过变形也可转化为乘法运算。
#include#include "ctype.h" int main() { int x[10087]={0},y[10087]={0},z[10087]={0}; //1.首先定义用于存储输入数字的数组x、y,以及用于存储结果的数组z; int xl=0,yl=0; //2.xl、yl分别表示两输入数字的位数; char c,o; //3.字符c用于将输入数字转化为数组;字符o表示运算符/操作符; while((c=getchar())!='n') { if (isdigit(c)) { x[xl] = c - '0'; xl++; } else { o = c; break; } } //4.第一次读取用于读取第一个输入数字x,x的位数xl,及运算符号o; while((c=getchar())!='n'){ if(isdigit(c)){ y[yl]=c-'0'; yl++; } } //5.第二次读取用于读取第二个输入数字y,y的位数yl; int a,b,sum=0; //6.a、b为(数组长度-1),即数组的最后一个数的序号; a = xl-1; b = yl-1; if(o=='-'){ for (int i=0;i =0||b>=0;i--){ sum = 0; if(a>=0&&b<0){ sum = x[a]; a--; } else if(a<0&&b>=0){ sum = y[b]; b--; } else{ sum = x[a]+y[b]; a--; b--; } sum += z[i]; if(sum>=10){ z[i]=sum%10; z[i-1]++; } else if(sum<0){ z[i]=sum+10; z[i-1]--; } else{ z[i]=sum; } } //8.计算答案,并用数组z存储答案; int i=0; while(z[i]==0&&i<10087) i++; //9.去除数组前列的无意义的零;123456-12345 if(z[i]==0) { printf("0");} else if(z[i]<0){ for(int j=i+1;j<10087;j++){ if(z[j]>=1){ z[j-1]++; z[j]-=10; } } for(int k=0;k<10087;k++){ for(int j=k;j<10087;j++){ if(z[j]>0) { z[j]-=10; z[j-1]++; } } } while(z[i]==0&&i<10087) i++; printf("-"); for(i;i<10087;i++) printf("%d",z[i]*-1); } //10.结果为负数时整理结果的结构并输出; else{ while(z[i]==0&&i<10087) i++; if(i==10087) printf("0"); for(i;i<10087;i++) printf("%d",z[i]); } //11.结果为非负数时直接输出; return 0; }
测试数据及结果分析
Test1
2022-2022
0
Test2
123456-12345
111111
Test3
4984189049807980-9817263083728510678
-9812278894678702698
Test4
1234567891111111+666666689410
1235234557800521
Test5
21009200371+21009200371
42018400742
第一组数据代表相减得0的例子;
第二组数据表示小数字一般相减;
第三组数据表示大数字一般相减;
第四组数据表示大数字一般相加;
第五组数据表示小数字一般相加;
结果均正确,推得程序无误。



