10、大数,高精度计算---百位大数

来源:互联网 发布:淘宝助理很卡 编辑:程序博客网 时间:2024/05/22 10:57

大数是算法语言中的数据类型无法表示的数,其位数超过最大数据类型所能表示的范围,所以,在处理大数问题时首先要考虑的是怎样存储大数,然后是在这种存储方式下其处理的实现方法。

一般情况下大数的存储是采用字符数组来存储,即将大数当作一个字符串来存储,而对其处理是按其处理规则在数组中模拟实现。

七 百位大数。

百位大数...让人又爱又恨阿。  回想去年,初学c语言,实验就有这个。
那时候折腾老久了。            刻苦铭心呀。
写这篇博客,没其他意思,主要是为了回忆回忆,然后记录一下当初的代码,便于以后翻看。

代码是大一上学期写的。可能比较水,大神们勿喷,纯属自己娱乐罢了。
 
实验题目:

此次实验要求利用数组实现两个百位大数(共有100位数字)的加、减、乘法的运算。
实现下列三个函数的功能(以下函数应在fun.h中声明,在fun.c中实现)
  函数原型:

/*实现两个大数的相加*/
   char* add(char* data, char* addend, char* result);

/*实现两个大数的相减*/
   char* minus(char* data, char* sub, char* result);

/*实现两个大数的相乘*/
   char* multiply(char* data, char* mult, char* result);

 

实验内容:

在给出的程序框架中完成实验题目。
mylib.c包括此次实验的程序框架。
 (在给出的程序框架中补充设计并完成实验。)

注:检验计算结果是否正确可利用提供的 test.exe 文件。
在mylib.exe和test.exe文件中输入相同的种子则会产生相同的随机大数。可以用test.exe产生的结果和mylib.exe对照结果检验对错。

请注意其中test.exe文件的输出格式和框架规定的输出格式有所不同。

 

提示:

字符型与整型转换

1.可以模拟笔算加减乘的过程,用数组储存大数;
2.可以用atoi和itoa函数;
3.对于一位整数的整型转换为字符型:

例:
char c;
int i = 9;
c = i+’0’;
printf(“%c”, c);

 



main.c

[cpp] view plaincopy
  1. /* 姓名:**** 
  2.    班级:软件三班 
  3.    学号:**** 
  4.    功能:百位大数 
  5.    时间:2012.12.2  */  
  6. #include <stdio.h>  
  7. #include <stdlib.h>  
  8. #include <string.h>  
  9. #include "fun.h"  
  10.   
  11. #define N 100  
  12.   
  13. /* 产生随机的大数  */  
  14. void create(char* num, unsigned seed);  /*seed 为随机种子*/  
  15.   
  16. char result[2 * N] = {'\0'};  
  17.   
  18. int main(void)  
  19. {  
  20.     char num[N];//多出符号位  
  21.     char n[N];  
  22.   
  23.     //设定随机种子  
  24.     unsigned int seed;  
  25.     printf("Please input a  rand seed:");  
  26.     scanf("%u", &seed);  
  27.     printf("\nThe seed is %u\n", seed);  
  28.   //产生随机大数  
  29.     create(num, seed);  
  30.     create(n, seed+1);  
  31.     printf("***********************************************\n");  
  32.     printf("num: %s\n n : %s\n", num, n);  
  33.   
  34.     //调用加法  
  35.     add(num, n, result);  
  36.     printf("num + n = %s\n", result);  
  37.   
  38.     //调用减法  
  39.     minus(num, n, result);  
  40.     printf("num - n = %s\n", result);  
  41.   
  42.     //调用乘法  
  43.     multiply(num, n, result);  
  44.     printf("num * n = %s\n", result);  
  45.   
  46.     system("pause");  
  47.     return 0;  
  48. }  
  49.   
  50. void create(char num[], unsigned seed)  
  51. {  
  52.     int i = 0, x = 0;  
  53.     int times, flag = 1;  
  54.     srand(seed);  
  55.     times = rand() % (N - 2) + 1;//避免溢出  
  56.     if(rand() % 2)//随机生成负数  
  57. {  
  58.         num[i] = '-';  
  59.         i++;  
  60.         if(times == 1)  
  61.             times++;  
  62.     }  
  63.     while(flag)//避免高位为零  
  64.     {  
  65.         x = rand() % 10;  
  66.         if(x != 0)  
  67.         {  
  68.             flag = 0;  
  69.         }  
  70.     }  
  71.     num[i] = x + '0';  
  72.     i++;  
  73.     for(; i < times; i++)  
  74.     {  
  75.         x = rand() % 10;  
  76.         num[i] = x + '0';  
  77.     }  
  78.     num[times] = '\0';  
  79. }  

fun.h

[cpp] view plaincopy
  1. #ifndef FUN_H_INCLUDED  
  2. #define FUN_H_INCLUDED  
  3.   
  4. //此方法实现加法运算  
  5. char* add(char* data, char* addend, char* result);  
  6.   
  7. //此方法实现减法运算  
  8. char* minus(char* data, char* sub, char* result);  
  9.   
  10. //此方法实现乘法运算  
  11. char* multiply(char* data, char* mult, char* result);  
  12.   
  13.   
  14. #endif // FUN_H_INCLUDED  


fun.c

[cpp] view plaincopy
  1. #include<stdio.h>  
  2. #include<stdlib.h>  
  3. #include"fun.h"  
  4. #include<string.h>  
  5.   
  6. #define N 100  
  7.   
  8. //在此添加加法的实现  
  9. char* add(char* data, char* addend, char* result)  
  10. {  
  11.     int i=0,a1,a2;  
  12.     char pdata[2*N]={'\0'};  
  13.     char padden[2*N]={'\0'};//定义两个char类型的字符数组,并初始化每一位都置为'\0'  
  14.     a1=strlen(data);  
  15.     a2=strlen(addend);//统计两个数组中字符串长度  
  16.     strcpy(pdata,data);//将字符串data复制到字符数组pdata[N]中  
  17.     strcpy(padden,addend);//将字符串addend复制到字符数组padden[N]中  
  18. for(i=0;result!='\0'&&i<2*N;i++)//将字符数组result[2*N]初始化每一位都置为'\0'  
  19.     {  
  20.       result[i]='\0';  
  21.     }  
  22.     if(pdata[0]!='-'&&padden[0]!='-')//当两个数均为正整数时  
  23.     {  
  24.       if(a1 >= a2)//第一个数的长度大于第二个数时  
  25.       {  
  26.         for(;a2>0;a2--,a1--)//两个正数对应位相加  
  27.         {  
  28.           result[a1-1]=pdata[a1-1]+padden[a2-1]-'0';//将相加得到的字符结果转化为数字字符  
  29.           if(result[a1-1]>'9'&&(a1-1)>0)//考虑进位的情况  
  30.           {  
  31.             result[a1-1] -= 10;  
  32.             pdata[a1-2]++;  
  33.           }  
  34.         }  
  35.         for(;a1>=1;a1--)//第一个数比第二个数多余的位数和'0'相加得到的结果  
  36.         {  
  37.           result[a1-1]=result[a1-1]+pdata[a1-1];  
  38.           if(result[a1-1]>'9'&&(a1-1)>0)  
  39.           {  
  40.             result[a1-1]-=10;//考虑到进位的情况  
  41.             pdata[a1-2]++;  
  42.           }  
  43.         }  
  44.         if(result[0]>'9')//当result[]中第一位>'9',要进行进位操作  
  45.         {  
  46.           a1=strlen(data);  
  47.           for(;a1>0;a1--)  
  48.           {  
  49.             result[a1]=result[a1-1];  
  50.           }  
  51.           result[1]-=10;  
  52.           result[0]='1';//首位进位加'1'  
  53.         }  
  54.       }  
  55.       else if(a1<a2)//第一个数的长度小于第二个数时,可以将加数与被加数调换再调用函数add()  
  56.       {       add(addend,data,result);  
  57.       }  
  58.     }  
  59.     else if(pdata[0]=='-'&&padden[0]=='-'//当为两个数都为负数时  
  60.     {  
  61.       result[0]='-';//result[]数组中第一位应为'-'  
  62.       add(&data[1],&addend[1],&result[1]);  
  63.     }  
  64.     else if(pdata[0]!='-'&&padden[0]=='-')//当第一个为正,第二个为负时,可以看做两个数相减,调用下面的minus()  
  65.     {  
  66.       minus(pdata,&padden[1],result);  
  67.     }  
  68.     else //当第一个为负,第二个为正时  
  69.     {  
  70.       add(addend,data,result);  
  71.     }  
  72.     return result;  
  73. }//在此添加减法的实现  
  74. char* minus(char* data, char* sub, char* result)  
  75. {  
  76.     int i,b1,b2,p,dif;  
  77.     char pdata[N]={'\0'}, psub[N]={'\0'};  
  78.     strcpy(pdata,data);//将字符串data复制到字符数组pdata[N]中  
  79.     strcpy(psub,sub);//将字符串sub复制到字符数组psub[N]中  
  80.     for(i=0;result[i]!='\0'&&i<N;i++)//将字符数组result[2*N]初始化每一位都置为'\0'  
  81.     {  
  82.       result[i]='\0';  
  83.     }  
  84.     b1=strlen(pdata);  
  85.     b2=strlen(psub);  
  86.     if(pdata[0]!='-'&&psub[0]!='-')//两个数都为正数  
  87.     {  
  88.       if(b1>b2)//第一个数位数大于第二个数时  
  89.       {  
  90.         for(;b2-1>=0;b1--,b2--)//两个正数对应位相减  
  91.  {  
  92.           result[b1-1]=pdata[b1-1]-psub[b2-1]+'0';//将相减得到的字符结果转化为数字字符  
  93.           if(result[b1-1]<'0')//考虑相减小于0的情况,要移位处理  
  94.           {  
  95.             result[b1-1]+=10;  
  96.             pdata[b1-2]--;  
  97.           }  
  98.         }  
  99.         p=b1;  
  100.         while (pdata[p-1]<'0'&&p>1)//当两个对应数相减小于'0'时,要位处理  
  101.         {  
  102.           pdata[p-1]+=10;  
  103.           pdata[p-2]--;  
  104.           p--;  
  105.         }  
  106.         if(b1>1)//第一个数比第二个数多余的位数和'0'相减得到的结果全部赋给result[]  
  107.         {  
  108.           for(;b1>0;b1--)  
  109.           {  
  110.             result[b1-1]=pdata[b1-1];  
  111.           }  
  112.         }  
  113.         while (result[0]=='0')//当移位相减后首位为'0'时  
  114.         {  
  115.           b1=strlen(pdata);  
  116.           for(i=0;i<=b1;i++)  
  117.           {  
  118.             result[i]=result[i+1];//要将result[]中的数都向前移一位  
  119.           }  
  120.         }  
  121.     }  
  122.     else if(b1 < b2)//第一个数位数大于第二个数时  
  123.   
  124.     {  
  125.       result[0]='-';//result[]数组中第一位应为'-'  
  126.       minus(psub,pdata,&result[1]);//将减数与被减数置换,再调用minus()  
  127.  }  
  128.     else//第一个数位数等于第二个数时  
  129.     {  
  130.       if(pdata[0]!=psub[0])//考虑两个数组第一个数是否相等  
  131.       {  
  132.         for(i=0;pdata[i]!=psub[i];i++)  
  133.        {  
  134.           ;  
  135.        }  
  136.        dif=i;//如果不相等下标digit设为i  
  137.   
  138.       }  
  139.       else  
  140.       {  
  141.         dif=0;//如果相等下标digit设为0  
  142.       }  
  143.       if(pdata[dif]>psub[dif])//当第一个数组中元素对应数值大于相同位的第二个数组中的元素  
  144.       {  
  145.         for(i=( b1-dif ) ; i > 0 ; i --,b1--,dif--)//对应位上的数值相减  
  146.         {  
  147.           result[b1-dif-1] =pdata[ b1-1 ] +'0'- psub[b2-1];//将相减得到的字符结果转化为数字字符  
  148.           if(result[b1-dif-1] < '0')  
  149.           {  
  150.             pdata[ b1-2 ]--;  
  151.             result[b1-dif-1] += 10;  
  152.           }  
  153.         }  
  154.         while (result[0]=='0')//当两个数组第一位数值相同,减去得到的结果为0  
  155.         {  
  156.           for(i = 0 ;i < b1-dif ; i++)//要将result[]数组中所有数向前移一位  
  157.           {  
  158.             result[i]=result[i+1];  
  159.           }  
  160.         }  
  161.       }  
  162.       else if(pdata[dif] < psub[dif])//当第一个数组中元素对应数值小于相同位的第二个数组中的元素  
  163.  {  
  164.         result[0]='-';//两个数组第一位元素相减对应数值小于0,想减结果第一位为'-'  
  165.         for(i = b1;i > 0 ; i--)  
  166.         {  
  167.           pdata[i] = pdata[i-1];//要pdata[]数组中所有数向后移一位  
  168.         }  
  169.           pdata[0] = '-';//相当于一个一个正数和一个负数做加法  
  170.           add(psub,&pdata[1],&result[1]);//调用加法函数add()  
  171.       }  
  172.       else//当第一个数组中元素对应数值等于相同位的第二个数组中的元素  
  173.       {  
  174.         result[0]='0';  
  175.         result[1]='\0';//最终result[]输出结果为0  
  176.       }  
  177.     }  
  178.    }  
  179.    else if(pdata[0]=='-'&&psub[0]!='-')//当第一个为负,第二个为正时,可以看做一个负数和一个正数做加法,调用加法函数add()  
  180.    {  
  181.      result[0]='-';  
  182.      add(&pdata[1],psub,&result[1]);  
  183.    }  
  184.    else if(pdata[0]!='-'&&psub[0]=='-')//当第一个为正,第二个为负时,可以看做一个正数和一个负数做加法,调用加法函数add()  
  185.    {  
  186.     add(pdata,&psub[1],result);  
  187.    }  
  188.    else  
  189.    {  
  190.     minus(&sub[1],&data[1],result);//当两个数都为负时,调用减法函数 minus()  
  191.    }  
  192.    return result;  
  193. }  
  194. //在此添加乘法的实现  
  195.  char *multiply(char* data, char* mult, char* result)  
  196. {  
  197.     int digit,i,k,c1,c2,c3,num;  
  198.     char pdata[N]={'\0'};  
  199.     char pmult[N]={'\0'};//定义两个char类型的字符数组,并初始化每一位都置为'\0'  
  200.     char array[2*N]={'\0'};//定义一个数组array[],用来存放第二个数每位相乘第一个数得到的结果  
  201.     strcpy(pdata,data);//将字符串data复制到字符数组pdata[N]中  
  202.     strcpy(pmult,mult);//将字符串mult复制到字符数组pmult[N]中  
  203.     c1=strlen(data);  
  204.     c2=strlen(mult);//统计两个数组中字符串长度  
  205.     for(i=0;result[i]!='\0'&&i<2*N;i++)//将字符数组result[2*N]初始化每一位都置为'\0'  
  206.     {  
  207.       result[i]='\0';  
  208.     }  
  209.     if(pdata[0]!='-'&&pmult[0]!='-')//当相乘的两个数均为正整数时  
  210.     {  
  211.       for(i=c1-1;i>=0;i--)  
  212.       {  
  213.         digit=c1-i-1;//统计array[]中需储存元素位数  
  214.         num=pdata[i]-'0';  
  215.         if(num>0)//当num>0时,将array[]先全部初始化每一位都置为'\0'  
  216.         {  
  217.           for(k=0;array[k]!='\0'&&k<2*N;k++)  
  218.           {  
  219.             array[k]='\0';  
  220.           }  
  221.           for(;num>0;num--)//mult[]数组中每一位对应数值数,相应array[]中元素要乘以相同倍数,可以通过连续加法来实现  
  222.           {  
  223.             add(array,pmult,array);  
  224.           }  
  225.            c3=strlen(array);//重新统计新得到的数组array[]中字符串长度  
  226.           for(;digit>0;digit--)  
  227. {  
  228.             array[c3+digit-1]='0';  
  229.           }  
  230.           add(array,result,result);//需将array[]中的元素错位累加即可得到最终相乘的结果  
  231.         }  
  232.       }  
  233.     }  
  234.     else if(pdata[0]=='-'&&pmult[0]!='-')//当第一个为负,第二个为正时,相乘结果第一位必为'-',再调用函数multiply[]  
  235.     {  
  236.       result[0]='-';  
  237.       multiply(&pdata[1],pmult,&result[1]);  
  238.     }  
  239.     else if(pdata[0]!='-'&&pmult[0]=='-')//当第一个为正,第二个为负时,相乘结果第一位必为'-',再调用函数multiply[]  
  240.     {  
  241.       result[0]='-';  
  242.       multiply(pdata,&pmult[1],&result[1]);  
  243.     }  
  244.     else if(pdata[0]=='-'&&pmult[0]=='-')//当两个数均为负整数时,相当于两个正整数相乘,调用函数multiply[]  
  245.     {  
  246.       multiply(&pdata[1],&pmult[1],result);  
  247.     }  
  248.     return result;  
  249. }  
0 0
原创粉丝点击