xref: /csrg-svn/lib/libmp/madd.c (revision 61321)
148370Sbostic /*-
248370Sbostic  * %sccs.include.proprietary.c%
348370Sbostic  */
448370Sbostic 
519819Sdist #ifndef lint
6*61321Sbostic static char sccsid[] = "@(#)madd.c	8.1 (Berkeley) 06/04/93";
748370Sbostic #endif /* not lint */
819819Sdist 
99945Ssam #include <mp.h>
109945Ssam m_add(a,b,c) struct mint *a,*b,*c;
119945Ssam {	int carry,i;
129945Ssam 	int x;
139945Ssam 	short *cval;
149945Ssam 	cval=xalloc(a->len+1,"m_add");
159945Ssam 	carry=0;
169945Ssam 	for(i=0;i<b->len;i++)
179945Ssam 	{	x=carry+a->val[i]+b->val[i];
189945Ssam 		if(x&0100000)
199945Ssam 		{	carry=1;
209945Ssam 			cval[i]=x&077777;
219945Ssam 		}
229945Ssam 		else
239945Ssam 		{	carry=0;
249945Ssam 			cval[i]=x;
259945Ssam 		}
269945Ssam 	}
279945Ssam 	for(;i<a->len;i++)
289945Ssam 	{	x=carry+a->val[i];
299945Ssam 		if(x&0100000) cval[i]=x&077777;
309945Ssam 		else
319945Ssam 		{	carry=0;
329945Ssam 			cval[i]=x;
339945Ssam 		}
349945Ssam 
359945Ssam 	}
369945Ssam 	if(carry==1)
379945Ssam 	{	cval[i]=1;
389945Ssam 		c->len=i+1;
399945Ssam 	}
409945Ssam 	else c->len=a->len;
419945Ssam 	c->val=cval;
429945Ssam 	if(c->len==0) shfree(cval);
439945Ssam 	return;
449945Ssam }
459945Ssam madd(a,b,c) struct mint *a,*b,*c;
469945Ssam {	struct mint x,y,z;
479945Ssam 	int sign;
489945Ssam 	x.len=a->len;
499945Ssam 	x.val=a->val;
509945Ssam 	y.len=b->len;
519945Ssam 	y.val=b->val;
529945Ssam 	z.len=0;
539945Ssam 	sign=1;
549945Ssam 	if(x.len>=0)
559945Ssam 		if(y.len>=0)
569945Ssam 			if(x.len>=y.len) m_add(&x,&y,&z);
579945Ssam 			else m_add(&y,&x,&z);
589945Ssam 		else
599945Ssam 		{	y.len= -y.len;
609945Ssam 			msub(&x,&y,&z);
619945Ssam 		}
629945Ssam 	else	if(y.len<=0)
639945Ssam 		{	x.len = -x.len;
649945Ssam 			y.len= -y.len;
659945Ssam 			sign= -1;
669945Ssam 			madd(&x,&y,&z);
679945Ssam 		}
689945Ssam 		else
699945Ssam 		{	x.len= -x.len;
709945Ssam 			msub(&y,&x,&z);
719945Ssam 		}
729945Ssam 	 xfree(c);
739945Ssam 	c->val=z.val;
749945Ssam 	c->len=sign*z.len;
759945Ssam 	return;
769945Ssam }
779945Ssam m_sub(a,b,c) struct mint *a,*b,*c;
789945Ssam {	int x,i;
799945Ssam 	int borrow;
809945Ssam 	short one;
819945Ssam 	struct mint mone;
829945Ssam 	one=1; mone.len= 1; mone.val= &one;
839945Ssam 	c->val=xalloc(a->len,"m_sub");
849945Ssam 	borrow=0;
859945Ssam 	for(i=0;i<b->len;i++)
869945Ssam 	{	x=borrow+a->val[i]-b->val[i];
879945Ssam 		if(x&0100000)
889945Ssam 		{	borrow= -1;
899945Ssam 			c->val[i]=x&077777;
909945Ssam 		}
919945Ssam 		else
929945Ssam 		{	borrow=0;
939945Ssam 			c->val[i]=x;
949945Ssam 		}
959945Ssam 	}
969945Ssam 	for(;i<a->len;i++)
979945Ssam 	{	x=borrow+a->val[i];
989945Ssam 		if(x&0100000) c->val[i]=x&077777;
999945Ssam 		else
1009945Ssam 		{	borrow=0;
1019945Ssam 			c->val[i]=x;
1029945Ssam 		}
1039945Ssam 	}
1049945Ssam 	if(borrow<0)
1059945Ssam 	{	for(i=0;i<a->len;i++) c->val[i] ^= 077777;
1069945Ssam 		c->len=a->len;
1079945Ssam 		madd(c,&mone,c);
1089945Ssam 	}
1099945Ssam 	for(i=a->len-1;i>=0;--i) if(c->val[i]>0)
1109945Ssam 				{	if(borrow==0) c->len=i+1;
1119945Ssam 					else c->len= -i-1;
1129945Ssam 					return;
1139945Ssam 				}
1149945Ssam 	shfree(c->val);
1159945Ssam 	return;
1169945Ssam }
1179945Ssam msub(a,b,c) struct mint *a,*b,*c;
1189945Ssam {	struct mint x,y,z;
1199945Ssam 	int sign;
1209945Ssam 	x.len=a->len;
1219945Ssam 	y.len=b->len;
1229945Ssam 	x.val=a->val;
1239945Ssam 	y.val=b->val;
1249945Ssam 	z.len=0;
1259945Ssam 	sign=1;
1269945Ssam 	if(x.len>=0)
1279945Ssam 		if(y.len>=0)
1289945Ssam 			if(x.len>=y.len) m_sub(&x,&y,&z);
1299945Ssam 			else
1309945Ssam 			{	sign= -1;
1319945Ssam 				msub(&y,&x,&z);
1329945Ssam 			}
1339945Ssam 		else
1349945Ssam 		{	y.len= -y.len;
1359945Ssam 			madd(&x,&y,&z);
1369945Ssam 		}
1379945Ssam 	else	if(y.len<=0)
1389945Ssam 		{	sign= -1;
1399945Ssam 			x.len= -x.len;
1409945Ssam 			y.len= -y.len;
1419945Ssam 			msub(&y,&x,&z);
1429945Ssam 		}
1439945Ssam 		else
1449945Ssam 		{	x.len= -x.len;
1459945Ssam 			madd(&x,&y,&z);
1469945Ssam 			sign= -1;
1479945Ssam 		}
1489945Ssam 	if(a==c && x.len!=0) xfree(a);
1499945Ssam 	else if(b==c && y.len!=0) xfree(b);
1509945Ssam 	else xfree(c);
1519945Ssam 	c->val=z.val;
1529945Ssam 	c->len=sign*z.len;
1539945Ssam 	return;
1549945Ssam }
155