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