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