xref: /original-bsd/lib/libmp/mult.c (revision 93ab02a6)
1 /*-
2  * %sccs.include.proprietary.c%
3  */
4 
5 #ifndef lint
6 static char sccsid[] = "@(#)mult.c	5.3 (Berkeley) 04/19/91";
7 #endif /* not lint */
8 
9 #include <mp.h>
10 mult(a,b,c) struct mint *a,*b,*c;
11 {	struct mint x,y,z;
12 	int sign;
13 	sign = 1;
14 	x.val=a->val;
15 	y.val=b->val;
16 	z.len=0;
17 	if(a->len<0)
18 	{	x.len= -a->len;
19 		sign= -sign;
20 	}
21 	else	x.len=a->len;
22 	if(b->len<0)
23 	{	y.len= -b->len;
24 		sign= -sign;
25 	}
26 	else	y.len=b->len;
27 	if(x.len<y.len) m_mult(&y,&x,&z);
28 	else m_mult(&x,&y,&z);
29 	xfree(c);
30 	if(sign<0) c->len= -z.len;
31 	else c->len=z.len;
32 	if(c->len==0) shfree(z.val);
33 	else c->val=z.val;
34 	return;
35 }
36 #define S2 x=a->val[j];
37 #define S3 x=x*b->val[i-j];
38 #define S4 tradd(&carry,&sum,x);
39 #define S5 c->val[i]=sum.yy.low&077777;
40 #define S6 sum.xx=sum.xx>>15;
41 #define S7 sum.yy.high=carry;
42 m_mult(a,b,c) struct mint *a,*b,*c;
43 {	long x;
44 	union {long xx; struct half yy;} sum;
45 	int carry;
46 	int i,j;
47 	c->val=xalloc(a->len+b->len,"m_mult");
48 	sum.xx=0;
49 	for(i=0;i<b->len;i++)
50 	{	carry=0;
51 		for(j=0;j<i+1;j++)
52 		{	S2
53 			S3
54 			S4
55 		}
56 		S5
57 		S6
58 		S7
59 	}
60 	for(;i<a->len;i++)
61 	{	carry=0;
62 		for(j=i-b->len+1;j<i+1;j++)
63 		{	S2
64 			S3
65 			S4
66 		}
67 		S5
68 		S6
69 		S7
70 	}
71 	for(;i<a->len+b->len;i++)
72 	{	carry=0;
73 		for(j=i-b->len+1;j<a->len;j++)
74 		{	S2
75 			S3
76 			S4
77 		}
78 		S5
79 		S6
80 		S7
81 	}
82 	if(c->val[i-1]!=0)
83 		c->len=a->len+b->len;
84 	else	c->len=a->len+b->len-1;
85 	return;
86 }
87 tradd(a,b,c) long c; int *a; union g {long xx; struct half yy;} *b;
88 {
89 	b->xx= b->xx+c;
90 	if(b->yy.high&0100000)
91 	{	b->yy.high= b->yy.high&077777;
92 		*a += 1;
93 	}
94 	return;
95 }
96