高精度
1 # include <stdio.h> 2 # include <string.h> 3 # define N 10000 4 5 char s1[N], s2[N]; 6 int a[N]; 7 8 int main(void) 9 { 10 while(~scanf("%s%*c%s", s1, s2)) 11 { 12 int n = strlen(s1)-1; 13 int m = strlen(s2)-1; 14 int t = 0; 15 int qian = 0; 16 while(n >= 0 && m >= 0) 17 { 18 a[t++] = (qian+(s1[n]-'0'+s2[m]-'0'))%10; 19 qian = (qian+(s1[n--]-'0'+s2[m--]-'0'))/10; 20 } 21 while(n >= 0) 22 { 23 a[t++] = (qian+s1[n]-'0')%10; 24 qian = (qian+s1[n--]-'0')/10; 25 } 26 while(m >= 0) 27 { 28 a[t++] = (qian+s2[m]-'0')%10; 29 qian = (qian+s2[m--]-'0')/10; 30 } 31 if(qian != 0) 32 printf("%d", qian); 33 for(int i = t-1; i >= 0; i--) 34 printf("%d", a[i]); 35 printf("\n"); 36 } 37 38 return 0; 39 } 40 41 42 43 44 /************************************** 45 Problem id : SDUT OJ 2448 46 User name : ranktop 47 Result : Accepted 48 Take Memory : 292K 49 Take Time : 0MS 50 Submit Time : 2013-08-16 16:05:20 51 **************************************/
先放在这 有空过来整理一下
1 高 精 度 算 法 2 #include <stdio.h> 3 #include <string.h> 4 #include <math.h> 5 #include <malloc.h> 6 int an,bn,fa=1,fb=1; /* 把an,bn,k设为全局变量,an纪录第一个高精度数组的位数,bn纪录第二个高精度数组的位数,k纪录输出结果的位数*/ 7 char b1[250], b2[250]; /*纪录需要计算的两个高精度数据 */ 8 void input(int a1[],int a2[]) /*函数input为输入函数,用来纪录两个待计算的高精度数据,以数组首地址为参数.以实现返回两个高精度数据*/ 9 { 10 int i,ai=1,bi=1; 11 scanf ( "%s%s", b1, b2 ); /*输入两个高精度数据 */ 12 an = strlen( b1 ); /*an纪录b1的位数 */ 13 bn = strlen( b2 ); /*bn纪录b2的位数 */ 14 if(b1[0]==45) 15 { 16 an--; /*判断数组的符号 */ 17 fa=-1; 18 ai=0; 19 } 20 if(b2[0]==45) 21 { 22 bn--; 23 fb=-1; 24 bi=0; 25 } 26 for (i=0; i<an; i++,ai++) 27 { 28 a1[i]=b1[an-ai]-'0'; /*把字符形数据b1转为整数形数据,同样用数组纪录 */ 29 printf("%d",a1[i]); 30 } 31 for (i=0; i<bn; i++,bi++) a2[i]=b2[bn-bi]-'0'; /* 同上 */ 32 return; 33 } 34 void addition(int a[],int b[],int q) /*高精度加法运算*/ 35 { 36 int i,c[251]= {0},k; 37 if(fa*fb>0||q) 38 { 39 if(an>bn) k=an; 40 else k=bn; /*用k纪录结果的最小位数*/ 41 for(i=0; i<k; i++) 42 { 43 c[i]=a[i]+b[i]+c[i]; 44 c[i+1]=(int)c[i]/10; 45 c[i]=(int)c[i]%10; 46 } /*高精度加法运算过程*/ 47 if(c[k]) k++; /*判断最后结果的位数*/ 48 if(fa<0&&q||fa<0) printf("-"); 49 for(i=k-1; i>=0; i--) printf("%d",c[i]); /*输出结果*/ 50 return; 51 } 52 else subtraction(a,b,1); 53 return; 54 } 55 subtraction(int a[],int b[],int q) /*高精度减法运算*/ 56 { 57 int i,f=0,c[251]= {0},k; 58 if(fa*fb>0||q) 59 { 60 if(an>bn) k=an; 61 else /*用k纪录结果的最大位数*/ 62 { 63 k=bn; 64 for(i=k; a[i]<=b[i]&&i>=0; i--) 65 if(a[i]<b[i]) f=1; /*f纪录结果符号*/ 66 } 67 if(!f) /*高精度减法运算过程*/ 68 for(i=0; i<k; i++) 69 { 70 if(a[i]<b[i]) 71 { 72 a[i+1]--; 73 a[i]+=10; 74 } 75 c[i]=a[i]-b[i]; 76 } 77 else /*当a<b时的处理*/ 78 for(i=0; i<k; i++) 79 { 80 if(b[i]<a[i]) 81 { 82 b[i+1]--; 83 b[i]+=10; 84 } 85 c[i]=b[i]-a[i]; 86 } 87 while(!c[k-1]&&k>1) k--; /*判断最后结果的位数*/ 88 if(q&&(fa>0&&f||fa<0&&!f)||fa>0&&(fb>0&&!f||f&&!q)) printf("-"); /*如果f为真是输出负号*/ 89 for(i=k-1; i>=0; i--) printf("%d",c[i]); 90 return; 91 } 92 else addition(a,b,1); 93 } 94 void multiplication( int a[], int b[]) /*高精度乘法运算*/ 95 { 96 int i, j, c[501] = {0},k; 97 k = an + bn - 1; /*用k纪录结果的最大位数*/ 98 for(i = 0; i < an; i++) /*高精度乘法运算过程*/ 99 for(j = 0; j < bn; j++) 100 { 101 c[i+j] = a[i] * b[j] + c[i+j]; 102 c[i+j+1] = c[i+j] / 10 + c[i+j+1]; 103 c[i+j] = c[i+j] % 10; 104 } 105 while(!c[k]) k--; /*判断最后结果的位数*/ 106 if(fa*fb<0) printf("-"); 107 for(i = k; i >= 0; i--) printf("%d",c[i]); /*输出结果*/ 108 } 109 main() 110 { 111 int a[250]= {0},b[250]= {0}; 112 input(a,b); 113 printf("\n%s+%s=",b1,b2); 114 addition(a,b,0); 115 printf("\n%s-%s=",b1,b2); 116 subtraction(a,b,0); 117 printf("\n%s*%s=",b1,b2); 118 multiplication(a,b); 119 getch(); 120 } 121 1、 高精度除以低精度; 122 算法:按照从高位到低位的顺序,逐位相除。在除到第j位时,该位在接受了来自第j+1位的余数后与除数相除,如果最高位为零,则商的长度减一。源程序如下: 123 #include <stdio.h> 124 #define N 500 125 main() 126 { 127 int a[N] = {0}, c[N] = {0}; 128 int i, k, d, b; 129 char a1[N]; 130 printf("Input 除数:"); 131 scanf("%d", &b); 132 printf("Input 被除数:"); 133 scanf("%s", a1); 134 k = strlen(a1); 135 for(i = 0; i < k; i++) a[i] = a1[k - i - 1] - '0'; 136 d = 0; 137 for(i = k - 1; i >= 0 ; i--) 138 { 139 d = d * 10 + a[i]; 140 c[i] = d / b; 141 d = d % b; 142 } 143 while(c[k - 1] == 0 && k > 1) k--; 144 printf("商="); 145 for(i = k - 1; i >= 0; i--) printf("%d", c[i]); 146 printf("\n余数=%d", d); 147 } 148 2、高精度乘以高精度(要求用尽可能少的存储单元); 149 算法:用数组保存两个高精度数,然后逐位相乘,注意考虑进位和总位数。源程序如下: #include <stdio.h> 150 main() 151 { 152 int a[240] = {0}, b[240] = {0}, c[480] = {0}; 153 int i, j, ka, kb, k; 154 char a1[240], b1[240]; 155 gets(a1); 156 ka = strlen(a1); 157 gets(b1); 158 kb = strlen(b1); 159 k = ka + kb; 160 for(i = 0; i < ka; i++) a[i] = a1[ka-i-1] - '0'; 161 for(i = 0; i < kb; i++) b[i] = b1[kb-i-1] - '0'; 162 for(i = 0; i < ka; i++) 163 for(j = 0; j < kb; j++) 164 { 165 c[i + j] = c[i + j] + a[i] * b[j]; 166 c[i + j +1] = c[i + j +1] + c[i + j]/10; 167 c[i + j] = c[i + j] % 10; 168 } 169 if(!c[k]) k--; 170 for(i = k-1; i >= 0; i--) printf("%d", c[i]); 171 } 172 3、高精度除以高精度(要求用尽可能少的存储单元); 173 算法:用计算机模拟手算除法,把除法试商转化为连减。 174 #include <stdio.h> 175 #define N 500 176 int bj(int a[], int b[], int k1, int k2) /*比较大小函数*/ 177 { 178 int i, t, flag; /*flag作标志位*/ 179 if(k1 < k2) 180 flag = 0; /*被除数小于除数返回0*/ 181 else if(k1 > k2) 182 flag = 1; /*被除数大于除数返回1*/ 183 else 184 { 185 /*被除数和除数位数相等则逐位进行比较*/ i = k1; 186 t = 0; 187 while(t == 0 && i > 0) 188 { 189 if(a[i] > b[i]) 190 { 191 t = 1; 192 flag = 1; 193 } 194 else if(a[i] == b[i]) i--; 195 else 196 { 197 t = 1; 198 flag = 0; 199 } 200 } 201 if(i == 0 && t == 0) flag = 2; /*被除数等于除数返回2*/ 202 } 203 return flag; 204 } 205 int jf(int a[], int b[], int k1, int k2) /*减法运算*/ 206 { 207 int i, k, d[N]; 208 for(i = 0; i < k2; i++) d[i] = b[i]; /*把除数赋给数组d*/ 209 for(i = k2; i < N; i++) d[i] = 0; /*d数组无数据的高位置0*/ 210 k = k1 - k2 - 1; /*计算减法起始位置*/ 211 if(k < 0) k = 0; 212 if(k > 0) 213 { 214 for(i = k2 - 1; i >= 0; i--) d[i + k] = d[i]; /*移动减数位数与被减数对齐*/ 215 for(i = 0; i < k; i++) d[i] = 0; /*移动后的其余位置0*/ 216 } 217 for(i = 0; i < k1; i++) 218 { 219 if(a[i] >= d[i]) a[i] -= d[i]; 220 else 221 { 222 a[i + 1] = a[i + 1] - 1; 223 a[i] = 10 + a[i] - d[i]; 224 } 225 } 226 return k; 227 } 228 main() 229 { 230 int a[N] = {0}, b[N] = {0}, c[N] = {0}, d[N] = {0}; 231 int i, ka, kb, m, t, t1, t2, k, x, kd, kk; 232 char a1[N], b1[N]; 233 printf("Input 被除数:"); 234 scanf("%s", a1); 235 ka = strlen(a1); 236 for(i = 0; i < ka; i++) a[i] = a1[ka - i -1] - '0'; 237 printf("Input 除数:"); 238 scanf("%s", b1); 239 kb = strlen(b1); 240 for(i = 0; i < kb; i++) b[i] = b1[kb - i -1] - '0'; 241 kd = ka; /*保存被除数位数 */ 242 t2 = bj(a, b, ka, kb); 243 m = 0; 244 do 245 { 246 while(a[ka - 1] == 0) ka--; 247 t = bj(a, b, ka, kb); 248 if(t >= 1) 249 { 250 k = jf(a, b, ka, kb); 251 c[k]++; 252 if(k > m) m = k; 253 t1 = 0; 254 for(i = k; i <= m; i++) 255 { 256 x = c[i] + t1; 257 c[i] = x % 10; 258 t1 = x / 10; 259 } 260 if(t1 > 0) 261 { 262 m++; 263 c[m] = t1; 264 } 265 } 266 } 267 while(t == 1); 268 if(t2 == 0) 269 { 270 printf("商=0"); 271 printf("\n余数="); 272 for(i = kd - 1; i >= 0; i--) printf("%d", a[i]); 273 exit(1); 274 } 275 if(t2 == 2) 276 { 277 printf("商 = 1"); 278 printf("\n余数 = 0"); 279 exit(1); 280 } 281 kk = kd; 282 while(!c[kd - 1]) kd--; 283 printf("商 = "); 284 for(i = kd - 1; i >= 0; i--) printf("%d", c[i]); 285 while(!a[kk]) kk--; 286 printf("\n余数 = "); 287 if(kk < 0) 288 { 289 printf("0"); 290 exit(1); 291 } 292 for(i = kk; i >= 0; i--) printf("%d", a[i]); 293 } 294 4、 N!,要求精确到P位(0〈P〈1000〉。 295 算法:结果用数组a保存,开始时a[0]=1,依次乘以数组中各位,注意进位和数组长度的变化。源程序如下: 296 #include <stdio.h> 297 #define M 1000 298 main() 299 { 300 int a[M], i, n, j, flag = 1; 301 printf("n="); 302 scanf("%d",&n); 303 printf("n!="); 304 a[0] = 1; 305 for(i = 1; i < M; i++) a[i] = 0; 306 for(j = 2; j <= n; j++) 307 { 308 for(i = 0; i < flag; i++) a[i] *= j; 309 for(i = 0; i < flag; i++) 310 if(a[i] >= 10) 311 { 312 a[i+1] += a[i]/10; 313 a[i] = a[i] % 10; 314 if(i == flag-1) flag++; 315 } 316 } 317 for(j = flag - 1; j >= 0; j--) 318 printf("%d", a[j]); 319 }

浙公网安备 33010602011771号