前言:
前面介绍了有关的思想,和本片博客的测试环境,所以作为第二篇的减法篇就不再过多的介绍,直接开始关于大数加法的实现。
大数减法:
与加法类似,还是将用户的输入和结果放入变长的数组中然后模仿手工运算从低位到高位依次相减,会有三个需要解决的问题,其中前二个和大数加法的问题很相似,所以就不再详细说明。
问题:
1.结果最多有多少位?
2.借位的算法如何实现?
3.如果一个8位数减去4位数,那么8位数较高的4位如何处理?
前两个问题参考大数加法都可以得到解决。
1.结果的最大位数和较大的减数位数相同,所以结果数组的长度可以和减数位数相同。
2.同加法类似,先存储每位相减的结果然后在用一个循环作整理。
3.可以把被减数缺少的位数用零补全然后相减,也可以只减到被减数的位数,然后将减数的高位直接写道结果的数组中。
注意:
本算法只可以拿大数减小数,因为小数减大数只不过还是拿大的减小的然后加个负号而已,所以本着简洁的原则,只允许用大数减去小数。
实现:
同加法一样还是把减法写成方法,然后在mian函数中调用,下面是完整的有详细注释的代码。
1 //#include"big.h"
2 #include<stdlib.h>
3 #include<stdio.h>
4 #include<string.h>
5 char * bigsub(char *suba,int lena,char *subb,int lenb){ //大数减法的的方法。
6 int lensum,num='0';
7 int i,j,k,tmp;
8 lensum=lena>lenb?lena:lenb;
9 for(i=0;i<lena;i++){ //将ASCII编码的数字转换为真正的数字存储,便于计算。
10 suba[i]=suba[i]-num; //大数加法注释中有例子。
11 }
12 for(i=0;i<lenb;i++){
13 subb[i]=subb[i]-num;
14 }
15 char *result,final[BUFSIZ];
16 result=(char*)calloc(lensum,1); //动态分配内存空间,在大数加法中忘记介绍
17 for(i=0,j=0;i<lena&&j<lenb;i++,j++){ //calloc()有两个参数,本次会分配 ‘lensum’ 个大小为 ‘1’ 字节的内存空间
18 result[i]=suba[lena-i-1]-subb[lenb-i-1]; //并且全部初始化为0,返回指向内存的指针
19 }
20 if(lena>lenb){ //判断,并将高位写入result结果数组中。
21 for(i=lenb;i<lena;i++){
22 result[i]=suba[lena-i-1];
23 }
24 }
25 if(lenb>lena){ //由于只允许大减小所以这个判断可以删除。
26 for(i=lena;i<lenb;i++){
27 result[i]=subb[lenb-i-1];
28 }
29 }
30 for(k=0;k<lensum-1;k++){ //整理结果,同大数加法类似,只是判断方法变了而已。
31 if(result[k]<0){
32 result[k]=result[k]+10;
33 result[k+1] -=1;
34 }
35 }
36 j=0;
37 if(result[lensum-1]!=0){ //将结果集去除前导0后整理到final数组中。
38 final[j]=result[lensum-1]+num;
39 j++;
40 }
41 for(i=lensum-2;i>=0;i--){
42 final[j++]=result[i]+num;
43
44 }
45 result=final; //将指针指向final数组并返回数组的指针。
46 return result;
47 }
48 int main(){ //利用main测试方法,用puts打印结果。
49 int lena,lenb;
50 char *result,sa[BUFSIZ],sb[BUFSIZ];
51 scanf("%s",sa);
52 scanf("%s",sb);
53 lena=strlen(sa);
54 lenb=strlen(sb);
55 result=bigsub(sa,lena,sb,lenb);
56 puts(result);
57
58 }
下一篇是大数乘法和除法。