高精度

来源:互联网 发布:linux网卡配置文件路径 编辑:程序博客网 时间:2024/04/30 00:02
 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 **************************************/
View Code

 

 先放在这  有空过来整理一下

  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 500125 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 500176 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     else184     {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             else196             {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         else221         {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     do245     {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 1000298         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 }
View Code

 

 

 

0 0