大数模板(高精度)

 
1
#include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <math.h> 5 #include <assert.h> 6 #include <ctype.h> 7 #include <map> 8 #include <string> 9 #include <set> 10 #include <bitset> 11 #include <utility> 12 #include <algorithm> 13 #include <vector> 14 #include <stack> 15 #include <queue> 16 #include <iostream> 17 #include <fstream> 18 #include <list> 19 using namespace std; 20 21 const int MAXL = 500; 22 struct BigNum 23 { 24 int num[MAXL]; 25 int len; 26 BigNum() 27 { 28 memset(num,0,sizeof(num)); 29 } 30 }; 31 32 //高精度比较 a > b return 1, a == b return 0; a < b return -1; 33 int Comp(BigNum &a, BigNum &b) 34 { 35 int i; 36 if(a.len != b.len) return (a.len > b.len) ? 1 : -1; 37 for(i = a.len-1; i >= 0; i--) 38 if(a.num[i] != b.num[i]) return (a.num[i] > b.num[i]) ? 1 : -1; 39 return 0; 40 } 41 42 //高精度加法 43 BigNum Add(BigNum &a, BigNum &b) 44 { 45 BigNum c; 46 int i, len; 47 len = (a.len > b.len) ? a.len : b.len; 48 memset(c.num, 0, sizeof(c.num)); 49 for(i = 0; i < len; i++) 50 { 51 c.num[i] += (a.num[i]+b.num[i]); 52 if(c.num[i] >= 10) 53 { 54 c.num[i+1]++; 55 c.num[i] -= 10; 56 } 57 } 58 if(c.num[len]) 59 len++; 60 c.len = len; 61 return c; 62 } 63 //高精度减法,保证a >= b 64 BigNum Sub(BigNum &a, BigNum &b) 65 { 66 BigNum c; 67 int i, len; 68 len = (a.len > b.len) ? a.len : b.len; 69 memset(c.num, 0, sizeof(c.num)); 70 for(i = 0; i < len; i++) 71 { 72 c.num[i] += (a.num[i]-b.num[i]); 73 if(c.num[i] < 0) 74 { 75 c.num[i] += 10; 76 c.num[i+1]--; 77 } 78 } 79 while(c.num[len] == 0 && len > 1) 80 len--; 81 c.len = len; 82 return c; 83 } 84 //高精度乘以低精度,当b很大时可能会发生溢出int范围,具体情况具体分析 85 //如果b很大可以考虑把b看成高精度 86 BigNum Mul1(BigNum &a, int &b) 87 { 88 BigNum c; 89 int i, len; 90 len = a.len; 91 memset(c.num, 0, sizeof(c.num)); 92 //乘以0,直接返回0 93 if(b == 0) 94 { 95 c.len = 1; 96 return c; 97 } 98 for(i = 0; i < len; i++) 99 { 100 c.num[i] += (a.num[i]*b); 101 if(c.num[i] >= 10) 102 { 103 c.num[i+1] = c.num[i]/10; 104 c.num[i] %= 10; 105 } 106 } 107 while(c.num[len] > 0) 108 { 109 c.num[len+1] = c.num[len]/10; 110 c.num[len++] %= 10; 111 } 112 c.len = len; 113 return c; 114 } 115 116 //高精度乘以高精度,注意要及时进位,否则肯能会引起溢出,但这样会增加算法的复杂度, 117 //如果确定不会发生溢出, 可以将里面的while改成if 118 BigNum Mul2(BigNum &a, BigNum &b) 119 { 120 int i, j, len = 0; 121 BigNum c; 122 memset(c.num, 0, sizeof(c.num)); 123 for(i = 0; i < a.len; i++) 124 { 125 for(j = 0; j < b.len; j++) 126 { 127 c.num[i+j] += (a.num[i]*b.num[j]); 128 if(c.num[i+j] >= 10) 129 { 130 c.num[i+j+1] += c.num[i+j]/10; 131 c.num[i+j] %= 10; 132 } 133 } 134 } 135 len = a.len+b.len-1; 136 while(c.num[len-1] == 0 && len > 1) 137 len--; 138 if(c.num[len]) 139 len++; 140 c.len = len; 141 return c; 142 } 143 144 //高精度除以低精度,除的结果为c, 余数为f 145 void Div1(BigNum &a, int &b, BigNum &c, int &f) 146 { 147 int i, len = a.len; 148 memset(c.num, 0, sizeof(c.num)); 149 f = 0; 150 for(i = a.len-1; i >= 0; i--) 151 { 152 f = f*10+a.num[i]; 153 c.num[i] = f/b; 154 f %= b; 155 } 156 while(len > 1 && c.num[len-1] == 0) 157 len--; 158 c.len = len; 159 } 160 //高精度*10 161 void Mul10(BigNum &a) 162 { 163 int i, len = a.len; 164 for(i = len; i >= 1; i--) 165 a.num[i] = a.num[i-1]; 166 a.num[i] = 0; 167 len++; 168 //if a == 0 169 while(len > 1 && a.num[len-1] == 0) 170 len--; 171 } 172 173 //高精度除以高精度,除的结果为c,余数为f 174 void Div2(BigNum &a, BigNum &b, BigNum &c, BigNum &f) 175 { 176 int i, len = a.len; 177 memset(c.num, 0, sizeof(c.num)); 178 memset(f.num, 0, sizeof(f.num)); 179 f.len = 1; 180 for(i = len-1;i >= 0;i--) 181 { 182 Mul10(f); 183 //余数每次乘10 184 f.num[0] = a.num[i]; 185 //然后余数加上下一位 186 ///利用减法替换除法 187 while(Comp(f, b) >= 0) 188 { 189 f = Sub(f, b); 190 c.num[i]++; 191 } 192 } 193 while(len > 1 && c.num[len-1] == 0) 194 len--; 195 c.len = len; 196 } 197 void print(BigNum &a) //输出大数 198 { 199 int i; 200 for(i = a.len-1; i >= 0; i--) 201 printf("%d", a.num[i]); 202 puts(""); 203 } 204 //将字符串转为大数存在BigNum结构体里面 205 BigNum ToNum(char *s) 206 { 207 int i, j; 208 BigNum a; 209 a.len = strlen(s); 210 for(i = 0, j = a.len-1; s[i] != '\0'; i++, j--) 211 a.num[i] = s[j]-'0'; 212 return a; 213 } 214 215 void Init(BigNum &a, char *s, int &tag) //将字符串转化为大数 216 { 217 int i = 0, j = strlen(s); 218 if(s[0] == '-') 219 { 220 j--; 221 i++; 222 tag *= -1; 223 } 224 a.len = j; 225 for(; s[i] != '\0'; i++, j--) 226 a.num[j-1] = s[i]-'0'; 227 } 228 229 int main(void) 230 { 231 BigNum a, b; 232 char s1[100], s2[100]; 233 while(scanf("%s %s", s1, s2) != EOF) 234 { 235 int tag = 1; 236 Init(a, s1, tag); //将字符串转化为大数 237 Init(b, s2, tag); 238 a = Mul2(a, b); 239 if(a.len == 1 && a.num[0] == 0) 240 { 241 puts("0"); 242 } 243 else 244 { 245 if(tag < 0) putchar('-'); 246 print(a); 247 } 248 } 249 return 0; 250 }

 

//高精度比较 a > b return 1, a == b return 0; a < b return -1;
//int Comp(BigNum &a, BigNum &b)

//高精度加法
//BigNum Add(BigNum &a, BigNum &b)

//高精度减法,保证a >= b
//BigNum Sub(BigNum &a, BigNum &b)

//高精度乘以低精度,当b很大时可能会发生溢出int范围,具体情况具体分析
//如果b很大可以考虑把b看成高精度
//BigNum Mul1(BigNum &a, int &b)

//高精度乘以高精度,注意要及时进位,否则肯能会引起溢出,但这样会增加算法的复杂度,
//如果确定不会发生溢出, 可以将里面的while改成if
//BigNum Mul2(BigNum &a, BigNum &b)

//高精度除以低精度,除的结果为c, 余数为f
//void Div1(BigNum &a, int &b, BigNum &c, int &f)

//高精度*10
//void Mul10(BigNum &a)

//高精度除以高精度,除的结果为c,余数为f
//void Div2(BigNum &a, BigNum &b, BigNum &c, BigNum &f)

//void print(BigNum &a)
//输出大数

//将字符串转为大数存在BigNum结构体里面
//BigNum ToNum(char *s)

//void Init(BigNum &a, char *s, int &tag)
//将字符串转化为大数

 

posted @ 2015-03-13 09:58  煎饼馃子  阅读(135)  评论(0编辑  收藏  举报