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