高精度运算

为了后面课程准备,先把基础的大数高精度运算先实现一遍。

  1 为了后面课程准备,先把基础的大数高精度运算先实现一遍。
  2 
  3 //BIGN.h
  4 
  5 #ifndef BIGN_H
  6 #define BIGN_H
  7 
  8 #include <iostream>
  9 #include <vector>
 10 #include <string>
 11 using namespace std;
 12 const int MAXN = 3000;
 13 
 14 //三元组gcd(a,b) = ax + by = d
 15 struct gcd
 16 {
 17     int x;
 18     int y;
 19     int d;
 20 };
 21 
 22 
 23 class bign
 24 {
 25 private:
 26     int n;   //参数n
 27     gcd m;   //定义一个三元组,使用欧几里得算法来进行递归求出最大公因子
 28 public:
 29     //阶乘的精确值
 30     string factorial(int n);
 31     
 32     /**
 33      *注:由于我们研究的密码学群Z的范围在{0,1,2,....,n-1}当中
 34      *故下面的大数相加,大数相减,大数相乘并没有考虑出现负数的情况
 35      */
 36 
 37     //大数相加
 38     string add(string a,string b);
 39 
 40     //大数相减
 41     //默认s1>=s2,未处理负数情况
 42     string sub(string a,string b);
 43 
 44     //大数相乘
 45     //未考虑负数相乘的情况
 46     string mul(string a,string b);
 47 
 48     //返回一个十进制数的二进制长度
 49     int BitLength(int x);
 50 
 51     //返回x的二进制表示中从低到高的第i位
 52     int BitAt(int x,int i);
 53 
 54     //返回值:a^b mod n 的值
 55     //通过模重复平方法
 56     int Modular_Expoent(int a,int b,int n);
 57 
 58     //返回一个三元组
 59     gcd extended_Euclid(int a,int b);
 60 
 61     //模逆运算
 62     int inverse(int a,int m);
 63 };
 64 
 65 string bign::factorial(int n)
 66 {
 67     string result;
 68     vector<long long> ff;
 69     ff.resize(MAXN);
 70     ff[0] = 1;
 71     int i,j;
 72     for(i = 2;i <= n;i++)
 73     {
 74         long long c = 0;
 75         for(j = 0;j < MAXN;j++)
 76         {
 77             long long s = ff[j] * i + c;   //模拟乘法的过程
 78             ff[j] = s % 10;
 79             c = s /10;
 80         }
 81     }
 82     for(j = MAXN - 1;j >= 0;j--)
 83     {
 84         if(ff[j])
 85             break;
 86     }
 87     for(i = j;i >= 0;i--)
 88     {
 89         result += (ff[i] + '0');
 90     }
 91     return  result;
 92 }
 93 
 94 
 95 string bign::add(string a,string b)
 96 {
 97     string result;
 98     string rr;
 99     int i;
100     int l1,l2,len1,len2;
101     l1 = len1 = a.size();
102     l2 = len2 = b.size();
103     int aa,bb,cc,dd;
104     dd = 0;
105     while(l1 > 0 && l2 > 0)
106     {
107         aa = a[l1-1] - '0';
108         bb = b[l2-1] - '0';
109         cc = (aa + bb+dd) % 10;
110         dd = (aa + bb+dd) / 10;
111         result += cc+'0';
112         l1--;
113         l2--;
114     }
115     while(l1 > 0)
116     {
117         aa = a[l1-1] - '0';
118         cc = (aa + dd) % 10;
119         dd = (aa + dd) / 10;
120         result += cc + '0';
121         l1--;
122     }
123     while(l2 > 0)
124     {
125         bb = b[l2-1] - '0';
126         cc = (bb + dd) % 10;
127         dd = (bb + dd) / 10;
128         result += cc + '0';
129         l2--;
130     }
131     if(dd == 1)
132         result += '1';
133     for(i = result.size() - 1;i >= 0 ;i--)
134         rr += result[i];
135     return rr;
136 }
137 
138 string bign::sub(string Max,string Min)
139 {
140     string result;
141     int lmax,lmin;
142     lmax = Max.size();
143     lmin = Min.size();
144     int i,j,k;
145     for(i = 0;i <= lmax;i++)
146         result += '0';
147     result[lmax] = '\0';
148     lmax--;
149     j = lmax;
150     for(i = lmin - 1;i >= 0;i--,j--)
151     {
152         if(Max[j] - Min[i] >= 0)
153         {
154             result[j] = Max[j] - Min[i] + '0';
155         }
156         else
157         {
158             result[j] = 10 + Max[j] - Min[i] + '0';
159             Max[j-1]--;
160         }
161     }
162     while(Max[j] < 0)
163     {
164         Max[j] += 10;
165         Max[j - 1]--;
166         j--;
167     }
168     while(j >= 0)
169     {
170         result[j] = Max[j];
171         j--;
172     }
173     return result;
174 }
175 
176 
177 string bign::mul(string aa,string bb)
178 {
179     if(aa == "0" || bb == "0")
180         return "0";
181     else
182     {
183         string result;
184         int i,j;
185         int len1 = aa.size();
186         int len2 = bb.size();
187         for(i = 0,j = len1 - 1;i <= j;i++,j--)
188         {
189             char temp = aa[i];
190             aa[i] = aa[j];
191             aa[j] = temp;
192         }
193         for(i = 0,j = len2 - 1;i <= j;i++,j--)
194         {
195             char temp = bb[i];
196             bb[i] = bb[j];
197             bb[j] = temp;
198         }
199         vector<int> c;
200         c.resize(MAXN);
201         for(i = 0;i < len1;i++)
202         {
203             for(j = 0;j < len2;j++)
204             {
205                 c[i+j] += (aa[i] - '0') * (bb[j] - '0');
206             }
207         }
208         int k = len1 + len2;
209         for(i = 0;i < k;i++)
210         {
211             if(c[i] > 9)
212             {
213                 c[i+1] += c[i] / 10;
214                 c[i] %= 10;
215             }
216         }
217         for(i = k - 1;i >= 0;i--)
218         {
219             if(c[i])
220                 break;
221         }
222         for(j = i;j >= 0;j--)
223         {
224             result += (c[j] + '0');
225         }
226         return result;
227     }
228 }
229 
230 int bign::BitLength(int x)
231 {
232     int d = 0;
233     while(x > 0)
234     {
235         x >>= 1;
236         d++;
237     }
238     return d;
239 }
240 
241 int bign::BitAt(int x,int i)
242 {
243     return ( x & (1 << (i - 1)) );
244 }
245 
246 int bign::Modular_Expoent(int a,int b,int n)
247 {
248     int i,y = 1;
249     for(i = BitLength(b);i > 0;i--)
250     {
251         y = (y * y) % n;
252         if(BitAt(b,i) > 0)
253             y = (y * a) % n;
254     }
255     return y;
256 }
257 
258 gcd bign::extended_Euclid(int a,int b)
259 {
260     gcd aa,bb;
261     if(b == 0)
262     {
263         aa.x = 1;
264         aa.y = 0;
265         aa.d = a;
266         return aa;
267     }
268     else
269     {
270         bb = extended_Euclid(b,a%b);
271         aa.x = bb.y;
272         aa.y = bb.x - (a / b) * bb.y;
273         aa.d = bb.d;
274     }
275     return aa;
276 }
277 
278 int bign::inverse(int a,int m)
279 {
280     gcd aa;
281     aa = extended_Euclid(a,m);
282     return aa.x;
283 }
284 #endif
285  

 

 

 

posted @ 2013-09-23 23:05  中大黑熊  阅读(414)  评论(0编辑  收藏  举报