玩具程序:bigInt

#0 为什么称作玩具程序?
1、实现简单,也就是效率一般。
2、只具备无符号数的加、乘运算功能。
 
#1 如何实现
以1792为例,用数组0号元素存储2,1号元素存储9,依此类推...
下面是大整数的存储结构图。

存储结构定义:

1  #define MAXDIGITS 64
2 
3 typedef  struct {
4      int lastdigit;
5      char digits[MAXDIGITS];
6 } bigNum;

加法实现:按位相加,再加上进位carry。两个数长度未必相同,所以高位的处理需要特别对待。
乘法实现:乘法其实是用加法来实现的,下面列出了伪码实现。

 1  int multiplyBigNum(bigNum * src, bigNum * dst){
 2     bigNum result;
 3     bigNum t;
 4 
 5      for each digit x  in dst{
 6         some bookkeeping;
 7         multiplyDigit(src, x, &t);
 8         addBigNum(&result, &t);
 9     }
10 
11     copyBigNum(&result, src);
12 
13      return  0;
14 }

#2 除了初始化bigInt外没有 除法、求余 运算:我构造了查找表,但这也使得程序代码变得更长了。
查找表的构造过程:写几行输出代码,控制台输入输出重定向,拷贝粘帖。如果是手工的话,很可能会出错。

 1     unsigned  char cacheMgr[ 96][ 2]={
 2          00,     01,     02,     03,     04,   
 3          05,     06,     07,     08,     09,   
 4          10,     11,     12,     13,     14,   
 5          15,     16,     17,     18,     19,   
 6          20,     21,     22,     23,     24,   
 7          25,     26,     27,     28,     29,   
 8          30,     31,     32,     33,     34,   
 9          35,     36,     37,     38,     39,   
10          40,     41,     42,     43,     44,   
11          45,     46,     47,     48,     49,   
12          50,     51,     52,     53,     54,   
13          55,     56,     57,     58,     59,   
14          60,     61,     62,     63,     64,   
15          65,     66,     67,     68,     69,   
16          70,     71,     72,     73,     74,   
17          75,     76,     77,     78,     79,   
18          80,     81,     82,     83,     84,   
19          85,     86,     87,     88,     89,   
20          90,     91,     92,     93,     94,   
21          95
22     };

#3 阶乘运算31!,改下参数运算256!也行的, 运行时间也会长些

 1  int main(){
 2     bigNum src;
 3     bigNum dst;
 4     
 5     makeBigNum( 1, &src);
 6     
 7      for ( int i= 1; i< 32; i++){
 8         makeBigNum(i, &dst);
 9         multiplyBigNum(&src, &dst);
10         printfBigNum(&src);
11     }
12 
13     getchar();
14      return  0;
15 }

#4 更多参考

显然,高精度数值运算程序库的编写可以称得上相当professional的工作!如果你想动手,最好找些帮手。【1】有递归实现。【2】有四则运算的完整实现。【3】有齐全的综述。【4】没看过,但显然里面会有权威的描述,必然会有的,哈哈。
【1】Eric S. Roberts. Programming Abstractions in C: A Second Course in Computer Science. Addison-Wesley Educational Publishers Inc.
【2】Steven S. Skiena Miguel A. Revilla. Programming Challenges. Springer Verlag. Ch5.2 High-Precision Integers.
【3】Steven S. Skiena. The Algorithm Design Manual, Second Edition. Springer-Verlag. Ch13.9 Arbitrary-Precision Arithmetic.
【4】D. Knuth. The Art of Computer Programming, Volume 2: Seminumerical Algorithms. Addison-Wesley, Reading MA, third edition, 1997.

#5 代码参考,拍砖请轻点下手

  1 #include <stdio.h>
  2 #include  " bigInt.h "
  3  #define MAXDIGITS 64
  4 
  5 typedef  struct {
  6      int lastdigit;
  7      char digits[MAXDIGITS];
  8 } bigNum;
  9 
 10  int makeBigNum( int src, bigNum * bn){
 11     bn->lastdigit = - 1;
 12      while (src !=  0){
 13         bn->lastdigit ++;
 14         bn->digits[bn->lastdigit] = src %  10;
 15         src = src /  10;
 16     }
 17 
 18      return  0;
 19 }
 20 
 21  int printfBigNum(bigNum * bn){
 22      for( int i=bn->lastdigit; i>= 0; i--){
 23         printf( " %u ", bn->digits[i]);
 24          if (i% 3 ==  0) printf( "   ");
 25     }
 26 
 27     printf( " \n ");
 28 
 29      return  0;
 30 }
 31 
 32  int addBigNum(bigNum * src, bigNum * dst){
 33     unsigned  char cacheMgr[ 20][ 2]={
 34          00,     01,     02,     03,     04,   
 35          05,     06,     07,     08,     09,   
 36           10,     11,     12,     13,     14,   
 37           15,     16,     17,     18,     19
 38     };
 39     
 40     bigNum * longNum = src;
 41      int shortLength = dst->lastdigit;
 42      if(dst->lastdigit > src->lastdigit){
 43         longNum = dst;
 44         shortLength = src->lastdigit;
 45     }
 46      int length = longNum->lastdigit;
 47 
 48      int carry =  0;
 49      for ( int i= 0; i<=shortLength; i++){
 50         unsigned  char t = src->digits[i] + dst->digits[i] + carry;
 51         src->digits[i] = cacheMgr[t][ 1];
 52         carry = cacheMgr[t][ 0];
 53     }
 54 
 55      for ( int i=shortLength+ 1; i<=length; i++){
 56         unsigned  char t = longNum->digits[i] + carry;
 57         src->digits[i] = cacheMgr[t][ 1];
 58         carry = cacheMgr[t][ 0];
 59     }
 60 
 61      if (carry ==  1){
 62         src->lastdigit = longNum->lastdigit+ 1;
 63         src->digits[src->lastdigit] =  1;
 64     }
 65      else src->lastdigit = longNum->lastdigit;
 66 
 67      return  0;
 68 }
 69 
 70  //  src =====> dst
 71  int copyBigNum(bigNum * src, bigNum * dst){
 72      int length = src->lastdigit;
 73     
 74     dst->lastdigit = length;
 75 
 76      for( int i= 0; i<=length; i++)
 77         dst->digits[i] = src->digits[i];
 78 
 79      return  0;
 80 }
 81 
 82  int multiplyDigit(bigNum * src, unsigned  char digit, bigNum * t){
 83     unsigned  char cacheMgr[ 96][ 2]={
 84          00,     01,     02,     03,     04,   
 85          05,     06,     07,     08,     09,   
 86          10,     11,     12,     13,     14,   
 87          15,     16,     17,     18,     19,   
 88          20,     21,     22,     23,     24,   
 89          25,     26,     27,     28,     29,   
 90          30,     31,     32,     33,     34,   
 91          35,     36,     37,     38,     39,   
 92          40,     41,     42,     43,     44,   
 93          45,     46,     47,     48,     49,   
 94          50,     51,     52,     53,     54,   
 95          55,     56,     57,     58,     59,   
 96          60,     61,     62,     63,     64,   
 97          65,     66,     67,     68,     69,   
 98          70,     71,     72,     73,     74,   
 99          75,     76,     77,     78,     79,   
100          80,     81,     82,     83,     84,   
101          85,     86,     87,     88,     89,   
102          90,     91,     92,     93,     94,   
103          95
104     };
105 
106      int carry =  0;
107      int length = src->lastdigit;
108      int x;
109 
110      for( int i= 0; i<=length; i++){
111         x = src->digits[i] * digit + carry;
112         t->lastdigit++;
113         t->digits[t->lastdigit] = cacheMgr[x][ 1];
114         carry = cacheMgr[x][ 0];
115     }
116 
117      if (carry >  0){
118         t->lastdigit = t->lastdigit+ 1;
119         t->digits[t->lastdigit] = carry;
120     }
121 
122      return  0;
123 }
124 
125  int multiplyBigNum(bigNum * src, bigNum * dst){
126     bigNum result;
127     bigNum t;
128 
129     makeBigNum( 0, &result);
130 
131      int length = dst->lastdigit;
132      for ( int i= 0; i<=length; i++){
133         t.lastdigit = i- 1;
134          for ( int s= 1; s<=i; s++)
135             t.digits[s- 1] =  0;
136         multiplyDigit(src, dst->digits[i], &t);
137         addBigNum(&result, &t);
138     }
139 
140     copyBigNum(&result, src);
141 
142      return  0;
143 }
144 
145  int main(){
146     bigNum src;
147     bigNum dst;
148     
149     makeBigNum( 1, &src);
150     
151      for ( int i= 1; i< 32; i++){
152         makeBigNum(i, &dst);
153         multiplyBigNum(&src, &dst);
154         printfBigNum(&src);
155     }
156 
157     getchar();
158      return  0;
159 }

 

转载于:https://www.cnblogs.com/servo/archive/2012/10/08/2715867.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值