BigNumCalculator
好久没写日志了,
其实草稿写了不少,
无论是感悟还是技术,
到最后却总是删掉,
总是觉得少了一股劲,
总越来越觉得自己还不够透彻。。。
上周时候,偶然同事讨论起了大数运算,
想起来自己以前做过一个BigNumCalculator 的阶乘计算器,
代码半天没找着,
打回家让老妈开了qq远程控制家里的电脑,
良久,才在一个很深的目录找到了代码,
忽然自己惊讶了,目录里还有很多自己过往写的代码,
从Web,各种DCC工具的练习,C++, DX。。。
好久未有这般感慨了,往日的一幕幕,浮现在眼前,
大学伊始,不准带电脑,
试过图书馆阅览室站一个早上看技术书,
然后破解一台角落处查书用的电脑,
然后站一个下午用记事本写代码,
像JS之类的就直接用IE测试,
抑或厚着脸皮买了鞋套,偷偷混进机房,
搞得几位机房的老师都认得我了;
有半年断网,
咬咬牙,买了一个NB的8G优盘,
然后在图书馆机房充值,
每周末去一次性准备好自己想看的资料,
然后回寝室慢慢啃。
现在想想挺酸楚的,
可仔细回想当时充满勇气和努力的自己,
我100%确定我当时是开心的,毫无保留地付出的,
反观今日的自己,物质上有了很大的充实,
同时也背负起了一些沉重遥远的现实目标,更多的时候,自己开始计较了。。。
这一切是我想要的么?
庆幸,
我现在还能找到当时的代码,
以及尚存的勇气和热血,
毋须多言,
翻开青涩的代码,
留下一个有趣的注释标头,
卯足劲,
一切从头开始,
明天还有好远,
继续,努力!
1 /*
2 091111
3 大数阶乘运算
4 节日快乐
5 -----Zephyr
6 */
7 /*
8 基本思路,化而治之
9 123456789
10 * 211
11 ---------
12 123456789
13 +1234567890
14 +24691357800
15 ------------
16 =26049382479
17 */
18 #include <iostream>
19 #include <stdio.h>
20 #include <windows.h>
21 #include <assert.h>
22 #include <conio.h>
23
24 #pragma comment(lib,"winmm.lib")
25 using namespace std;
26 const int MaxLength=128;
27 const int Max=MaxLength-1;
28
29 void Copy(int *des,int *src)
30 {
31 for(int j=Max;j>=0;j--)
32 {
33 des[j]=src[j];
34 }
35 }
36
37 void Zero(int *src)
38 {
39 for(int j=0;j<MaxLength;j++)
40 {
41 src[j]=0;
42 }
43 }
44
45 int GetLength(int *a)
46 {
47 int i=Max;
48 while( a[i] <= 0 && i> 0 )
49 --i;
50 return ++i;
51 }
52
53 void Increase(int *a1)
54 {
55 a1[Max]++;
56 for(int j=Max;j>0;j--)
57 {
58 if(a1[j]>10)
59 {
60 a1[j]-=10;
61 a1[j-1]++;
62 }
63 else
64 break;
65 }
66 }
67
68 //相加的时候向前提了k个位置
69 void Sum(int *sum,int * a,int k=0)
70 {
71 int j2;
72 //有漏洞,但可以把Max设大
73 for(int j=0 ;j < GetLength(a) ;++j)
74 {
75 j2= j+k;
76 sum[ j2 ]+=a[j];
77 //加法最大值应该只有 8+8 == 19
78 if(sum[ j2 ] >= 10)
79 {
80 if( j2 >= MaxLength )
81 assert("Over flow!");
82 if( sum[ j2 ]<0 || sum[ j2 ] > 19 )
83 assert("Oh no");
84 sum[j2]-=10;
85 if(sum[j2]>=10)
86 sum[j2]=0;
87 sum[j2+1]++;
88 }
89 }
90 }
91
92 void Multi(int *sum,int *aO,int k)//十进制乘法
93 {
94 if( k<0 || k> 9 )
95 assert("Wrong Number");
96 //a0*k送入结果sum中
97 int t=0;
98 //不能改变a0
99 Copy(sum,aO);
100 int j;
101 for( j=0 ; j < GetLength(aO) ; ++j )
102 {
103 sum[j]*=k;
104 if(t)
105 {
106 sum[j]+=t;
107 t=0;
108 }
109 //进位
110 if(sum[j] >= 10)
111 {
112 t=sum[j]/10;
113 sum[j]=sum[j]%10;
114 }
115 }
116 //最后一位还可能会进位
117 if(t)
118 {
119 sum[j]+=t;
120 }
121 }
122
123 void MultiX(int *total,int *t)//大数相乘
124 {
125 int temp[MaxLength];
126 int tempSum[MaxLength];
127 Zero( tempSum );
128 for(int j=0; j<GetLength( t ) ;++j)
129 {
130 Multi(temp,total,t[j]);
131 Sum(tempSum,temp,j);
132 }
133 Copy(total,tempSum);
134 }
135
136 void AnotherWay(int n)
137 {
138 //精确到12!看来你也不行哈。。。-_-!
139 //寻址问题
140 SIZE_T x=1;
141 int i=1;
142 while(i<=n)
143 {
144 x*=i;
145 i++;
146 }
147 cout<<"K.O:"<<endl<<x<<endl;
148 /*x=479001600;
149 x*=13;
150 cout<<x;*/
151 }
152
153 void main0()
154 {
155 int total[MaxLength],t[MaxLength];
156 int n;
157 float t1=0;
158 bool debug=0;
159 cout<<"输入阶乘级数:"<<endl;
160 cin>>n;
161 while(n>0)
162 {
163 t1=(float)timeGetTime();
164 Zero(total);Zero(t);
165 total[Max]=t[Max]=1;
166 AnotherWay(n);
167 n--;
168 int i=2;
169 while(n>0)//阶乘,从1*2*3*...*n
170 {
171 Increase(t);
172 MultiX(total,t);
173 if(debug)
174 {
175 cout<<"第"<<i++<<"层:"<<endl;//DeBug使用,i既是当前乘数
176 for(int j=MaxLength-GetLength(total);j<MaxLength;j++)
177 cout<<total[j];
178 cout<<endl;
179 }
180 n--;
181 }
182 cout<<"结果为:"<<endl;
183 for(int j=MaxLength-GetLength(total);j<MaxLength;j++)//从不为零的数位开始输出结果
184 cout<<total[j];
185 cout<<endl<<"用时:"<<(float)timeGetTime()-t1<<"ms"<<endl;
186 cout<<"-----------Over--------------"<<endl;
187 cout<<"输入阶乘级数(0结束):"<<endl;
188 cin>>n;
189 }
190 }
191
192 void GetABigNumber(int InVec[] )
193 {
194 int n;
195 int i=0;
196 char c;
197 //cin>>n;
198 //cin.get(c);
199 c=getch();
200 n=atoi(&c);
201 while ( n>= 0 && n < 10 )
202 {
203 if( i > 0)
204 {
205 int i1=i;
206 while( i1 > 0)
207 {
208 InVec[ i1 ]=InVec[i1-1];
209 --i1;
210 }
211 }
212 InVec[0]=n;
213 ++i;
214 c=getch();
215 n=atoi(&c);
216 }
217 }
218 void PraseString2BigNumber(int inVec[],char Srt[])
219 {
220 int length = strlen( Srt );
221 Zero(inVec);
222 char ch;
223 for (int i=length-1, j=0;j<length;++j)
224 {
225 ch=Srt[i--];
226 inVec[ j ]=atoi( &ch );
227 }
228 }
229 void main()
230 {
231 unsigned int p1=10;
232 unsigned int p2=0xa0000000;
233 float pw=p2/p1;
234 int total[MaxLength],t[MaxLength];
235 int n;
236 float t1=0;
237 bool debug=0;
238 /*
239 Zero(total);
240 Zero(t);
241 cout<<"输入第一个大数:"<<endl;
242 GetABigNumber(total);
243 cout<<"输入第二个大数:"<<endl;
244 GetABigNumber(t);
245 */
246 //char str1[]="12888";
247 //char str2[]="12888";
248 //16384
249 char str1[]="145682565648569854785693568458967890";
250 char str2[]="64318641564154513745146843514";
251 PraseString2BigNumber(total,str1);
252 PraseString2BigNumber(t,str2);
253 cout<<"第一个大数:"<<str1<<endl;
254 cout<<"乘以第二个大数:"<<str2<<endl;
255 t1=(float)timeGetTime();
256 MultiX(total,t);
257 cout<<"结果为:"<<endl;
258 for(int j=GetLength(total)-1 ;j>=0;--j)//从不为零的数位开始输出结果
259 cout<<total[j];
260 cout<<endl<<"用时:"<<(float)timeGetTime()-t1<<"ms"<<endl;
261 cout<<"-----------Over--------------"<<endl;
262 cin>>n;
263 }
2 091111
3 大数阶乘运算
4 节日快乐
5 -----Zephyr
6 */
7 /*
8 基本思路,化而治之
9 123456789
10 * 211
11 ---------
12 123456789
13 +1234567890
14 +24691357800
15 ------------
16 =26049382479
17 */
18 #include <iostream>
19 #include <stdio.h>
20 #include <windows.h>
21 #include <assert.h>
22 #include <conio.h>
23
24 #pragma comment(lib,"winmm.lib")
25 using namespace std;
26 const int MaxLength=128;
27 const int Max=MaxLength-1;
28
29 void Copy(int *des,int *src)
30 {
31 for(int j=Max;j>=0;j--)
32 {
33 des[j]=src[j];
34 }
35 }
36
37 void Zero(int *src)
38 {
39 for(int j=0;j<MaxLength;j++)
40 {
41 src[j]=0;
42 }
43 }
44
45 int GetLength(int *a)
46 {
47 int i=Max;
48 while( a[i] <= 0 && i> 0 )
49 --i;
50 return ++i;
51 }
52
53 void Increase(int *a1)
54 {
55 a1[Max]++;
56 for(int j=Max;j>0;j--)
57 {
58 if(a1[j]>10)
59 {
60 a1[j]-=10;
61 a1[j-1]++;
62 }
63 else
64 break;
65 }
66 }
67
68 //相加的时候向前提了k个位置
69 void Sum(int *sum,int * a,int k=0)
70 {
71 int j2;
72 //有漏洞,但可以把Max设大
73 for(int j=0 ;j < GetLength(a) ;++j)
74 {
75 j2= j+k;
76 sum[ j2 ]+=a[j];
77 //加法最大值应该只有 8+8 == 19
78 if(sum[ j2 ] >= 10)
79 {
80 if( j2 >= MaxLength )
81 assert("Over flow!");
82 if( sum[ j2 ]<0 || sum[ j2 ] > 19 )
83 assert("Oh no");
84 sum[j2]-=10;
85 if(sum[j2]>=10)
86 sum[j2]=0;
87 sum[j2+1]++;
88 }
89 }
90 }
91
92 void Multi(int *sum,int *aO,int k)//十进制乘法
93 {
94 if( k<0 || k> 9 )
95 assert("Wrong Number");
96 //a0*k送入结果sum中
97 int t=0;
98 //不能改变a0
99 Copy(sum,aO);
100 int j;
101 for( j=0 ; j < GetLength(aO) ; ++j )
102 {
103 sum[j]*=k;
104 if(t)
105 {
106 sum[j]+=t;
107 t=0;
108 }
109 //进位
110 if(sum[j] >= 10)
111 {
112 t=sum[j]/10;
113 sum[j]=sum[j]%10;
114 }
115 }
116 //最后一位还可能会进位
117 if(t)
118 {
119 sum[j]+=t;
120 }
121 }
122
123 void MultiX(int *total,int *t)//大数相乘
124 {
125 int temp[MaxLength];
126 int tempSum[MaxLength];
127 Zero( tempSum );
128 for(int j=0; j<GetLength( t ) ;++j)
129 {
130 Multi(temp,total,t[j]);
131 Sum(tempSum,temp,j);
132 }
133 Copy(total,tempSum);
134 }
135
136 void AnotherWay(int n)
137 {
138 //精确到12!看来你也不行哈。。。-_-!
139 //寻址问题
140 SIZE_T x=1;
141 int i=1;
142 while(i<=n)
143 {
144 x*=i;
145 i++;
146 }
147 cout<<"K.O:"<<endl<<x<<endl;
148 /*x=479001600;
149 x*=13;
150 cout<<x;*/
151 }
152
153 void main0()
154 {
155 int total[MaxLength],t[MaxLength];
156 int n;
157 float t1=0;
158 bool debug=0;
159 cout<<"输入阶乘级数:"<<endl;
160 cin>>n;
161 while(n>0)
162 {
163 t1=(float)timeGetTime();
164 Zero(total);Zero(t);
165 total[Max]=t[Max]=1;
166 AnotherWay(n);
167 n--;
168 int i=2;
169 while(n>0)//阶乘,从1*2*3*...*n
170 {
171 Increase(t);
172 MultiX(total,t);
173 if(debug)
174 {
175 cout<<"第"<<i++<<"层:"<<endl;//DeBug使用,i既是当前乘数
176 for(int j=MaxLength-GetLength(total);j<MaxLength;j++)
177 cout<<total[j];
178 cout<<endl;
179 }
180 n--;
181 }
182 cout<<"结果为:"<<endl;
183 for(int j=MaxLength-GetLength(total);j<MaxLength;j++)//从不为零的数位开始输出结果
184 cout<<total[j];
185 cout<<endl<<"用时:"<<(float)timeGetTime()-t1<<"ms"<<endl;
186 cout<<"-----------Over--------------"<<endl;
187 cout<<"输入阶乘级数(0结束):"<<endl;
188 cin>>n;
189 }
190 }
191
192 void GetABigNumber(int InVec[] )
193 {
194 int n;
195 int i=0;
196 char c;
197 //cin>>n;
198 //cin.get(c);
199 c=getch();
200 n=atoi(&c);
201 while ( n>= 0 && n < 10 )
202 {
203 if( i > 0)
204 {
205 int i1=i;
206 while( i1 > 0)
207 {
208 InVec[ i1 ]=InVec[i1-1];
209 --i1;
210 }
211 }
212 InVec[0]=n;
213 ++i;
214 c=getch();
215 n=atoi(&c);
216 }
217 }
218 void PraseString2BigNumber(int inVec[],char Srt[])
219 {
220 int length = strlen( Srt );
221 Zero(inVec);
222 char ch;
223 for (int i=length-1, j=0;j<length;++j)
224 {
225 ch=Srt[i--];
226 inVec[ j ]=atoi( &ch );
227 }
228 }
229 void main()
230 {
231 unsigned int p1=10;
232 unsigned int p2=0xa0000000;
233 float pw=p2/p1;
234 int total[MaxLength],t[MaxLength];
235 int n;
236 float t1=0;
237 bool debug=0;
238 /*
239 Zero(total);
240 Zero(t);
241 cout<<"输入第一个大数:"<<endl;
242 GetABigNumber(total);
243 cout<<"输入第二个大数:"<<endl;
244 GetABigNumber(t);
245 */
246 //char str1[]="12888";
247 //char str2[]="12888";
248 //16384
249 char str1[]="145682565648569854785693568458967890";
250 char str2[]="64318641564154513745146843514";
251 PraseString2BigNumber(total,str1);
252 PraseString2BigNumber(t,str2);
253 cout<<"第一个大数:"<<str1<<endl;
254 cout<<"乘以第二个大数:"<<str2<<endl;
255 t1=(float)timeGetTime();
256 MultiX(total,t);
257 cout<<"结果为:"<<endl;
258 for(int j=GetLength(total)-1 ;j>=0;--j)//从不为零的数位开始输出结果
259 cout<<total[j];
260 cout<<endl<<"用时:"<<(float)timeGetTime()-t1<<"ms"<<endl;
261 cout<<"-----------Over--------------"<<endl;
262 cin>>n;
263 }