为了后面课程准备,先把基础的大数高精度运算先实现一遍。
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] = '