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