声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 2752|回复: 0

[经典算法] [转帖]大数运算的乘除算法

[复制链接]
发表于 2005-10-4 10:18 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
#include &lt;stdio.h&gt; <BR>#include &lt;stdlib.h&gt; <BR>#include &lt;string.h&gt; <BR>#include &lt;ctype.h&gt; <BR><BR>int cchkdig(char *r) <BR>{ <BR>int i=0;  <BR>while(r!='\0') <BR>{ <BR>if(isdigit(r[i++])==0) <BR>return (0); <BR>} <BR>  return (1);  <BR>} <BR><BR>//去掉整数串表示前面多余的零,最后结果为空串时置为"0" <BR>void cdel0(char *r) <BR>{<BR>unsigned int lr;  <BR>int i=0, j; <BR>lr=strlen(r);  <BR>while(r=='0') <BR>  ++i;<BR>if(i&gt;0) <BR>{<BR>for(j=0; j&lt;lr-i; ++j)<BR>r[j]=r[j+i];<BR>for(j=lr-i; j&lt;lr; ++j) <BR>{<BR>r[j]='\0'; <BR>}<BR><BR>}<BR><BR>if(r[0]=='\0')<BR>{<BR>r[0]='0';<BR>} <BR>} <BR><BR>int scmp(char *r, char *u) <BR>{ <BR>unsigned int lr, lu; <BR>cdel0(r);<BR>cdel0(u); <BR><BR>lr=strlen(r); <BR>lu=strlen(u); <BR><BR>if(lr&gt;lu) <BR>{<BR>return 1;<BR>}<BR>else if (lr&lt;lu) <BR>{<BR>return -1;<BR>}<BR>return (strcmp(r, u)); <BR><BR>}//end scmp() <BR><BR>//两个串表示数的减法 <BR>char *ssub(char *r, char *u) <BR>{<BR>unsigned int i,lr, lu, lp,c=0;  <BR>char h,hc; <BR>char *p;<BR>if(scmp(r, u)&lt;0) <BR>return NULL; <BR>lr=strlen(r); <BR>lu=strlen(u); <BR>p=(char *)malloc((unsigned int)(lr+1)*sizeof(char)); <BR>for(i=0; i&lt;lu; ++i) <BR>{<BR>h=r[lr-i-1]-u[lu-i-1]-c; <BR>if(h&lt;0) <BR>{<BR>c=1; <BR>h=h+10;<BR>} <BR>else <BR>c=0; <BR>p=h+'0';<BR>hc=h+'0';<BR>} <BR>for (i=lu; i&lt;lr; ++i) <BR>{ <BR>h=r[lr-i-1]-'0'-c;<BR>if(h&lt;0) <BR>{<BR>c=1; <BR>h=h+10; <BR>} <BR>else <BR>c=0; <BR>p='0'+h; <BR>hc='0'+h;<BR>}<BR>p='\0';<BR>lp=i-1;<BR><BR>while(p[lp]=='0'&amp;&amp;lp!=0)<BR>{<BR>p[lp]='\0';<BR>lp--; <BR>}<BR><BR><BR>for(i=0; i&lt;(lp+1)/2; ++i) <BR>{ <BR>hc=p; <BR>p=p[lp-i]; <BR>p[lp-i]=hc; <BR>} <BR>return (p); <BR>}//end ssub() <BR><BR>//两个串表示数的加法 <BR>char *sadd(char *r, char *u) <BR>{ <BR>unsigned int lr, lu, lp; <BR>int i, h, c=0; <BR>char hc, *p; <BR>lr=strlen(r); <BR>lu=strlen(u); <BR>if(lu&gt;lr) <BR>{ <BR>p=r; <BR>r=u; <BR>u=p; <BR>h=lr; <BR>lr=lu; <BR>lu=h; <BR>} <BR>p=(char *)malloc((unsigned int)(lr+2)*sizeof(char));  <BR>for(i=0; i&lt;lu; ++i) <BR>{ <BR>h=r[lr-i-1]-'0'+u[lu-i-1]-'0'+c; <BR>if(h&gt;9) <BR>{ <BR>c=1;<BR>h=h-10; <BR>} <BR>else <BR>c=0;  <BR>p=h+'0';  <BR>} <BR>for(i=lu; i&lt;lr; ++i) <BR>{ <BR>h=r[lr-i-1]-'0'+c; <BR>if(h&gt;9) <BR>{ <BR>c=1; <BR>h=h-10; <BR>} <BR>else <BR>c=0;  <BR>p='0'+h;  <BR>} <BR>if(c&gt;0) <BR>{ <BR>p=c+'0'; <BR>lp=i; <BR>} <BR>else <BR>lp=i-1;  <BR>for(i=lp+1; i&lt;lr+2; ++i) <BR>p='\0'; <BR>for(i=0; i&lt;(lp+1)/2; ++i) <BR>{ <BR>hc=p; <BR>p=p[lp-i]; <BR>p[lp-i]=hc; <BR>} <BR>return (p); <BR>}//end sadd() <BR><BR>//两个串表示数的乘法 <BR>char *smut(char *r, char *u) <BR>{ <BR>unsigned int lr, lu, lp; <BR>int i, j, c, h; <BR>char *p; <BR>lr=strlen(r); <BR>lu=strlen(u); <BR>p=(char *)malloc((unsigned int)(lr+lu+1)*sizeof(char)); <BR>for(i=0; i&lt;lr+lu; ++i) <BR>p='0'; <BR>p[lr+lu]='\0'; <BR><BR>for(i=lr-1; i&gt;=0; --i) <BR>{ <BR>c=0;  <BR>for(j=lu-1; j&gt;=0; --j) <BR>{ <BR>lp=i+j+1;  <BR>h=(r-'0')*(u[j]-'0')+p[lp]-'0'+c;  <BR>c=h/10;  <BR>h=h%10;  <BR>p[lp]=h+'0';  <BR>} <BR>if(c&gt;0)p[i+j+1]=c+'0';  <BR>} <BR><BR>cdel0(p);  <BR>return p;  <BR>}//end smut() <BR><BR>//两个串表示数的除法,结果精确到小数点后第n位 <BR>char *sdivf(char *u, char *v, int n) <BR>{ <BR>char *p, *f, *r,*q;  <BR>unsigned int i, lu, lv, lr,  iw, c, h;  <BR>int  kh, j;  <BR>lu=strlen(u);  <BR>lv=strlen(v);  <BR>f=(char *)malloc((unsigned int)(lu+n+3)*sizeof(char)); <BR>q=(char *)malloc(sizeof(char)); <BR>for(i=0; i&lt;lu+n+3; ++i) <BR>f='\0'; <BR>r=(char *)malloc((unsigned int)(lv+2)*sizeof(char)); <BR>for(i=0; i&lt;lv+2; ++i) <BR>r='\0'; <BR>for(iw=0; iw&lt;lu+n+2; ++iw) <BR>{ <BR>if(iw&lt;lu) <BR>{ <BR>cdel0(r); <BR>lr=strlen(r); <BR>r[lr]=u[iw]; <BR>r[lr+1]='\0';<BR>} <BR><BR>else if(iw&gt;lu) <BR>{ <BR>cdel0(r);<BR>q[0]='0';<BR>if(scmp(r, q)==0)<BR>{<BR>break; <BR>}<BR>lr=strlen(r); <BR>r[lr]='0';<BR>r[lr+1]='\0'; <BR>} <BR><BR>else <BR>{ <BR>f[lu]='.'; <BR>continue;  <BR>}<BR><BR>kh=0; <BR>while(scmp(r, v)&gt;=0) <BR>{ <BR>p=r;<BR>r=ssub(p, v); <BR>++kh; <BR>} <BR>f[iw]=kh+'0'; <BR>} <BR>if(iw==lu+n+2) <BR>{ <BR>if(f[lu+n+1]&gt;='5') <BR>{ <BR>f[lu+n+1]='\0';  <BR>c=1;  <BR>for(j=lu+n; j&gt;=0; --j) <BR>{ <BR>if(c==0) <BR>{<BR>break;  <BR>}<BR>if(f[j]=='.')<BR>{<BR>continue; <BR>}<BR>h=f[j]-'0'+c;  <BR>if(h&gt;9) <BR>{ <BR>h=h-10; <BR>c=1; <BR>} <BR>else <BR>c='\0';  <BR>f[j]=h+'0'; <BR>} <BR>} <BR>else <BR>f[lu+n+1]='\0'; <BR><BR>} <BR>free(r); <BR>free(p);<BR>q=NULL;<BR>free(q);<BR>cdel0(f);  <BR>return(f);  <BR>}//end sdivf() <BR><BR>//两个串表示数的除法,结果分别用整商与余数表示 <BR>char *sdivkr(char *u, char *v, char **rout) <BR>{ <BR>char  *f, *r;  <BR>unsigned int i, lu, lv, lr, iw;  <BR>int  kh;  <BR>lu=strlen(u);  <BR>lv=strlen(v);  <BR><BR>f=(char *)malloc((unsigned int)(lu+1)*sizeof(char)); <BR>for(i=0; i&lt;lu+1; ++i) f='\0'; <BR>r=(char *)malloc((unsigned int)(lv+2)*sizeof(char)); <BR>for(i=0; i&lt;lv+2; ++i) r='\0'; <BR><BR>for(iw=0; iw&lt;lu; ++iw) <BR>{ <BR>cdel0(r); <BR>lr=strlen(r); <BR>r[lr]=u[iw]; <BR>r[lr+1]='\0'; <BR>kh=0; <BR>while(scmp(r, v)&gt;=0) <BR>{ <BR>r=ssub(r, v); <BR>++kh; <BR>} <BR>f[iw]=kh+'0'; <BR>} <BR>cdel0(r);  <BR>*rout=r;  <BR>cdel0(f); <BR>    return(f);<BR><BR>}//end *sdivkr() <BR><BR>//调用上述函数实现两任意长正整数任意指定精度的算术计算器程序 <BR>void main(int argc, char *argv[]) <BR>{ <BR>char *p, *r;  <BR>int n;  <BR>if(argc!=4)<BR>{ <BR>if(argc!=3)<BR>printf("\n&gt;&gt;\"order n1 op n2\" or n ! "); <BR>exit(0); <BR>} <BR>cdel0(argv[1]);  <BR>if(cchkdig(argv[1])==0)<BR>{ <BR>printf("Input data error, Input again!"); <BR>exit(0); <BR>} <BR>cdel0(argv[3]);  <BR>if(cchkdig(argv[3])==0) <BR>{ <BR>printf("Input data error, Input again!"); <BR>exit(0); <BR>} <BR><BR>if(strcmp(argv[2], "+")==0) <BR>{ <BR>printf("%s", p=sadd(argv[1], argv[3])); <BR>free(p); <BR>} <BR><BR>else if(strcmp(argv[2], "-")==0) <BR>{ <BR>printf("%s", p=ssub(argv[1], argv[3])); <BR>free(p); <BR>} <BR><BR>else if(strcmp(argv[2], "*")==0) <BR>{ <BR>printf("%s", p=smut(argv[1], argv[3])); <BR>free(p); <BR>} <BR><BR>else if(argv[2][0]=='/' &amp;&amp; strlen(argv[2])==1) <BR>{ <BR>if(argv[3][0]=='0')<BR>{<BR>printf("error!devided by zero!!\n");<BR>exit(0);<BR>}<BR>p=sdivkr(argv[1], argv[3], &amp;r);  <BR>printf("k=%s r=%s", p, r);  <BR>free(p); <BR>free(r);  <BR>} <BR><BR>else if(argv[2][0]=='/'&amp;&amp;strlen(argv[2])&gt;1) <BR>{ <BR>if(argv[3][0]=='0')<BR>{<BR>printf("error!devided by zero!!\n");<BR>exit(0);<BR>}<BR><BR>argv[2][0]='\0';  <BR>cdel0(argv[2]);  <BR>if(cchkdig(argv[2])==0) <BR>{ <BR>printf("Input data error, Input again!"); <BR>exit (0); <BR>} <BR>n=atoi(argv[2]);  <BR>printf("%s", p=sdivf(argv[1], argv[3], n));<BR>free(p);  <BR>} <BR><BR><BR>}
回复
分享到:

使用道具 举报

您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-4-28 04:51 , Processed in 0.080143 second(s), 17 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表