xref: /original-bsd/lib/libmp/madd.c (revision 79cf7955)
1 #ifndef lint
2 static char sccsid[] = "@(#)madd.c	5.2 (Berkeley) 03/02/87";
3 #endif not lint
4 
5 #include <mp.h>
6 m_add(a,b,c) struct mint *a,*b,*c;
7 {	int carry,i;
8 	int x;
9 	short *cval;
10 	cval=xalloc(a->len+1,"m_add");
11 	carry=0;
12 	for(i=0;i<b->len;i++)
13 	{	x=carry+a->val[i]+b->val[i];
14 		if(x&0100000)
15 		{	carry=1;
16 			cval[i]=x&077777;
17 		}
18 		else
19 		{	carry=0;
20 			cval[i]=x;
21 		}
22 	}
23 	for(;i<a->len;i++)
24 	{	x=carry+a->val[i];
25 		if(x&0100000) cval[i]=x&077777;
26 		else
27 		{	carry=0;
28 			cval[i]=x;
29 		}
30 
31 	}
32 	if(carry==1)
33 	{	cval[i]=1;
34 		c->len=i+1;
35 	}
36 	else c->len=a->len;
37 	c->val=cval;
38 	if(c->len==0) shfree(cval);
39 	return;
40 }
41 madd(a,b,c) struct mint *a,*b,*c;
42 {	struct mint x,y,z;
43 	int sign;
44 	x.len=a->len;
45 	x.val=a->val;
46 	y.len=b->len;
47 	y.val=b->val;
48 	z.len=0;
49 	sign=1;
50 	if(x.len>=0)
51 		if(y.len>=0)
52 			if(x.len>=y.len) m_add(&x,&y,&z);
53 			else m_add(&y,&x,&z);
54 		else
55 		{	y.len= -y.len;
56 			msub(&x,&y,&z);
57 		}
58 	else	if(y.len<=0)
59 		{	x.len = -x.len;
60 			y.len= -y.len;
61 			sign= -1;
62 			madd(&x,&y,&z);
63 		}
64 		else
65 		{	x.len= -x.len;
66 			msub(&y,&x,&z);
67 		}
68 	 xfree(c);
69 	c->val=z.val;
70 	c->len=sign*z.len;
71 	return;
72 }
73 m_sub(a,b,c) struct mint *a,*b,*c;
74 {	int x,i;
75 	int borrow;
76 	short one;
77 	struct mint mone;
78 	one=1; mone.len= 1; mone.val= &one;
79 	c->val=xalloc(a->len,"m_sub");
80 	borrow=0;
81 	for(i=0;i<b->len;i++)
82 	{	x=borrow+a->val[i]-b->val[i];
83 		if(x&0100000)
84 		{	borrow= -1;
85 			c->val[i]=x&077777;
86 		}
87 		else
88 		{	borrow=0;
89 			c->val[i]=x;
90 		}
91 	}
92 	for(;i<a->len;i++)
93 	{	x=borrow+a->val[i];
94 		if(x&0100000) c->val[i]=x&077777;
95 		else
96 		{	borrow=0;
97 			c->val[i]=x;
98 		}
99 	}
100 	if(borrow<0)
101 	{	for(i=0;i<a->len;i++) c->val[i] ^= 077777;
102 		c->len=a->len;
103 		madd(c,&mone,c);
104 	}
105 	for(i=a->len-1;i>=0;--i) if(c->val[i]>0)
106 				{	if(borrow==0) c->len=i+1;
107 					else c->len= -i-1;
108 					return;
109 				}
110 	shfree(c->val);
111 	return;
112 }
113 msub(a,b,c) struct mint *a,*b,*c;
114 {	struct mint x,y,z;
115 	int sign;
116 	x.len=a->len;
117 	y.len=b->len;
118 	x.val=a->val;
119 	y.val=b->val;
120 	z.len=0;
121 	sign=1;
122 	if(x.len>=0)
123 		if(y.len>=0)
124 			if(x.len>=y.len) m_sub(&x,&y,&z);
125 			else
126 			{	sign= -1;
127 				msub(&y,&x,&z);
128 			}
129 		else
130 		{	y.len= -y.len;
131 			madd(&x,&y,&z);
132 		}
133 	else	if(y.len<=0)
134 		{	sign= -1;
135 			x.len= -x.len;
136 			y.len= -y.len;
137 			msub(&y,&x,&z);
138 		}
139 		else
140 		{	x.len= -x.len;
141 			madd(&x,&y,&z);
142 			sign= -1;
143 		}
144 	if(a==c && x.len!=0) xfree(a);
145 	else if(b==c && y.len!=0) xfree(b);
146 	else xfree(c);
147 	c->val=z.val;
148 	c->len=sign*z.len;
149 	return;
150 }
151