xref: /plan9/sys/src/cmd/unix/drawterm/libmp/mpaux.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier #include "os.h"
2*8ccd4a63SDavid du Colombier #include <mp.h>
3*8ccd4a63SDavid du Colombier #include "dat.h"
4*8ccd4a63SDavid du Colombier 
5*8ccd4a63SDavid du Colombier static mpdigit _mptwodata[1] = { 2 };
6*8ccd4a63SDavid du Colombier static mpint _mptwo =
7*8ccd4a63SDavid du Colombier {
8*8ccd4a63SDavid du Colombier 	1,
9*8ccd4a63SDavid du Colombier 	1,
10*8ccd4a63SDavid du Colombier 	1,
11*8ccd4a63SDavid du Colombier 	_mptwodata,
12*8ccd4a63SDavid du Colombier 	MPstatic
13*8ccd4a63SDavid du Colombier };
14*8ccd4a63SDavid du Colombier mpint *mptwo = &_mptwo;
15*8ccd4a63SDavid du Colombier 
16*8ccd4a63SDavid du Colombier static mpdigit _mponedata[1] = { 1 };
17*8ccd4a63SDavid du Colombier static mpint _mpone =
18*8ccd4a63SDavid du Colombier {
19*8ccd4a63SDavid du Colombier 	1,
20*8ccd4a63SDavid du Colombier 	1,
21*8ccd4a63SDavid du Colombier 	1,
22*8ccd4a63SDavid du Colombier 	_mponedata,
23*8ccd4a63SDavid du Colombier 	MPstatic
24*8ccd4a63SDavid du Colombier };
25*8ccd4a63SDavid du Colombier mpint *mpone = &_mpone;
26*8ccd4a63SDavid du Colombier 
27*8ccd4a63SDavid du Colombier static mpdigit _mpzerodata[1] = { 0 };
28*8ccd4a63SDavid du Colombier static mpint _mpzero =
29*8ccd4a63SDavid du Colombier {
30*8ccd4a63SDavid du Colombier 	1,
31*8ccd4a63SDavid du Colombier 	1,
32*8ccd4a63SDavid du Colombier 	0,
33*8ccd4a63SDavid du Colombier 	_mpzerodata,
34*8ccd4a63SDavid du Colombier 	MPstatic
35*8ccd4a63SDavid du Colombier };
36*8ccd4a63SDavid du Colombier mpint *mpzero = &_mpzero;
37*8ccd4a63SDavid du Colombier 
38*8ccd4a63SDavid du Colombier static int mpmindigits = 33;
39*8ccd4a63SDavid du Colombier 
40*8ccd4a63SDavid du Colombier // set minimum digit allocation
41*8ccd4a63SDavid du Colombier void
mpsetminbits(int n)42*8ccd4a63SDavid du Colombier mpsetminbits(int n)
43*8ccd4a63SDavid du Colombier {
44*8ccd4a63SDavid du Colombier 	if(n == 0)
45*8ccd4a63SDavid du Colombier 		n = 1;
46*8ccd4a63SDavid du Colombier 	mpmindigits = DIGITS(n);
47*8ccd4a63SDavid du Colombier }
48*8ccd4a63SDavid du Colombier 
49*8ccd4a63SDavid du Colombier // allocate an n bit 0'd number
50*8ccd4a63SDavid du Colombier mpint*
mpnew(int n)51*8ccd4a63SDavid du Colombier mpnew(int n)
52*8ccd4a63SDavid du Colombier {
53*8ccd4a63SDavid du Colombier 	mpint *b;
54*8ccd4a63SDavid du Colombier 
55*8ccd4a63SDavid du Colombier 	b = mallocz(sizeof(mpint), 1);
56*8ccd4a63SDavid du Colombier 	if(b == nil)
57*8ccd4a63SDavid du Colombier 		sysfatal("mpnew: %r");
58*8ccd4a63SDavid du Colombier 	n = DIGITS(n);
59*8ccd4a63SDavid du Colombier 	if(n < mpmindigits)
60*8ccd4a63SDavid du Colombier 		n = mpmindigits;
61*8ccd4a63SDavid du Colombier 	n = n;
62*8ccd4a63SDavid du Colombier 	b->p = (mpdigit*)mallocz(n*Dbytes, 1);
63*8ccd4a63SDavid du Colombier 	if(b->p == nil)
64*8ccd4a63SDavid du Colombier 		sysfatal("mpnew: %r");
65*8ccd4a63SDavid du Colombier 	b->size = n;
66*8ccd4a63SDavid du Colombier 	b->sign = 1;
67*8ccd4a63SDavid du Colombier 
68*8ccd4a63SDavid du Colombier 	return b;
69*8ccd4a63SDavid du Colombier }
70*8ccd4a63SDavid du Colombier 
71*8ccd4a63SDavid du Colombier // guarantee at least n significant bits
72*8ccd4a63SDavid du Colombier void
mpbits(mpint * b,int m)73*8ccd4a63SDavid du Colombier mpbits(mpint *b, int m)
74*8ccd4a63SDavid du Colombier {
75*8ccd4a63SDavid du Colombier 	int n;
76*8ccd4a63SDavid du Colombier 
77*8ccd4a63SDavid du Colombier 	n = DIGITS(m);
78*8ccd4a63SDavid du Colombier 	if(b->size >= n){
79*8ccd4a63SDavid du Colombier 		if(b->top >= n)
80*8ccd4a63SDavid du Colombier 			return;
81*8ccd4a63SDavid du Colombier 		memset(&b->p[b->top], 0, Dbytes*(n - b->top));
82*8ccd4a63SDavid du Colombier 		b->top = n;
83*8ccd4a63SDavid du Colombier 		return;
84*8ccd4a63SDavid du Colombier 	}
85*8ccd4a63SDavid du Colombier 	b->p = (mpdigit*)realloc(b->p, n*Dbytes);
86*8ccd4a63SDavid du Colombier 	if(b->p == nil)
87*8ccd4a63SDavid du Colombier 		sysfatal("mpbits: %r");
88*8ccd4a63SDavid du Colombier 	memset(&b->p[b->top], 0, Dbytes*(n - b->top));
89*8ccd4a63SDavid du Colombier 	b->size = n;
90*8ccd4a63SDavid du Colombier 	b->top = n;
91*8ccd4a63SDavid du Colombier }
92*8ccd4a63SDavid du Colombier 
93*8ccd4a63SDavid du Colombier void
mpfree(mpint * b)94*8ccd4a63SDavid du Colombier mpfree(mpint *b)
95*8ccd4a63SDavid du Colombier {
96*8ccd4a63SDavid du Colombier 	if(b == nil)
97*8ccd4a63SDavid du Colombier 		return;
98*8ccd4a63SDavid du Colombier 	if(b->flags & MPstatic)
99*8ccd4a63SDavid du Colombier 		sysfatal("freeing mp constant");
100*8ccd4a63SDavid du Colombier 	memset(b->p, 0, b->top*Dbytes);	// information hiding
101*8ccd4a63SDavid du Colombier 	free(b->p);
102*8ccd4a63SDavid du Colombier 	free(b);
103*8ccd4a63SDavid du Colombier }
104*8ccd4a63SDavid du Colombier 
105*8ccd4a63SDavid du Colombier void
mpnorm(mpint * b)106*8ccd4a63SDavid du Colombier mpnorm(mpint *b)
107*8ccd4a63SDavid du Colombier {
108*8ccd4a63SDavid du Colombier 	int i;
109*8ccd4a63SDavid du Colombier 
110*8ccd4a63SDavid du Colombier 	for(i = b->top-1; i >= 0; i--)
111*8ccd4a63SDavid du Colombier 		if(b->p[i] != 0)
112*8ccd4a63SDavid du Colombier 			break;
113*8ccd4a63SDavid du Colombier 	b->top = i+1;
114*8ccd4a63SDavid du Colombier 	if(b->top == 0)
115*8ccd4a63SDavid du Colombier 		b->sign = 1;
116*8ccd4a63SDavid du Colombier }
117*8ccd4a63SDavid du Colombier 
118*8ccd4a63SDavid du Colombier mpint*
mpcopy(mpint * old)119*8ccd4a63SDavid du Colombier mpcopy(mpint *old)
120*8ccd4a63SDavid du Colombier {
121*8ccd4a63SDavid du Colombier 	mpint *new;
122*8ccd4a63SDavid du Colombier 
123*8ccd4a63SDavid du Colombier 	new = mpnew(Dbits*old->size);
124*8ccd4a63SDavid du Colombier 	new->top = old->top;
125*8ccd4a63SDavid du Colombier 	new->sign = old->sign;
126*8ccd4a63SDavid du Colombier 	memmove(new->p, old->p, Dbytes*old->top);
127*8ccd4a63SDavid du Colombier 	return new;
128*8ccd4a63SDavid du Colombier }
129*8ccd4a63SDavid du Colombier 
130*8ccd4a63SDavid du Colombier void
mpassign(mpint * old,mpint * new)131*8ccd4a63SDavid du Colombier mpassign(mpint *old, mpint *new)
132*8ccd4a63SDavid du Colombier {
133*8ccd4a63SDavid du Colombier 	mpbits(new, Dbits*old->top);
134*8ccd4a63SDavid du Colombier 	new->sign = old->sign;
135*8ccd4a63SDavid du Colombier 	new->top = old->top;
136*8ccd4a63SDavid du Colombier 	memmove(new->p, old->p, Dbytes*old->top);
137*8ccd4a63SDavid du Colombier }
138*8ccd4a63SDavid du Colombier 
139*8ccd4a63SDavid du Colombier // number of significant bits in mantissa
140*8ccd4a63SDavid du Colombier int
mpsignif(mpint * n)141*8ccd4a63SDavid du Colombier mpsignif(mpint *n)
142*8ccd4a63SDavid du Colombier {
143*8ccd4a63SDavid du Colombier 	int i, j;
144*8ccd4a63SDavid du Colombier 	mpdigit d;
145*8ccd4a63SDavid du Colombier 
146*8ccd4a63SDavid du Colombier 	if(n->top == 0)
147*8ccd4a63SDavid du Colombier 		return 0;
148*8ccd4a63SDavid du Colombier 	for(i = n->top-1; i >= 0; i--){
149*8ccd4a63SDavid du Colombier 		d = n->p[i];
150*8ccd4a63SDavid du Colombier 		for(j = Dbits-1; j >= 0; j--){
151*8ccd4a63SDavid du Colombier 			if(d & (((mpdigit)1)<<j))
152*8ccd4a63SDavid du Colombier 				return i*Dbits + j + 1;
153*8ccd4a63SDavid du Colombier 		}
154*8ccd4a63SDavid du Colombier 	}
155*8ccd4a63SDavid du Colombier 	return 0;
156*8ccd4a63SDavid du Colombier }
157*8ccd4a63SDavid du Colombier 
158*8ccd4a63SDavid du Colombier // k, where n = 2**k * q for odd q
159*8ccd4a63SDavid du Colombier int
mplowbits0(mpint * n)160*8ccd4a63SDavid du Colombier mplowbits0(mpint *n)
161*8ccd4a63SDavid du Colombier {
162*8ccd4a63SDavid du Colombier 	int k, bit, digit;
163*8ccd4a63SDavid du Colombier 	mpdigit d;
164*8ccd4a63SDavid du Colombier 
165*8ccd4a63SDavid du Colombier 	if(n->top==0)
166*8ccd4a63SDavid du Colombier 		return 0;
167*8ccd4a63SDavid du Colombier 	k = 0;
168*8ccd4a63SDavid du Colombier 	bit = 0;
169*8ccd4a63SDavid du Colombier 	digit = 0;
170*8ccd4a63SDavid du Colombier 	d = n->p[0];
171*8ccd4a63SDavid du Colombier 	for(;;){
172*8ccd4a63SDavid du Colombier 		if(d & (1<<bit))
173*8ccd4a63SDavid du Colombier 			break;
174*8ccd4a63SDavid du Colombier 		k++;
175*8ccd4a63SDavid du Colombier 		bit++;
176*8ccd4a63SDavid du Colombier 		if(bit==Dbits){
177*8ccd4a63SDavid du Colombier 			if(++digit >= n->top)
178*8ccd4a63SDavid du Colombier 				return 0;
179*8ccd4a63SDavid du Colombier 			d = n->p[digit];
180*8ccd4a63SDavid du Colombier 			bit = 0;
181*8ccd4a63SDavid du Colombier 		}
182*8ccd4a63SDavid du Colombier 	}
183*8ccd4a63SDavid du Colombier 	return k;
184*8ccd4a63SDavid du Colombier }
185*8ccd4a63SDavid du Colombier 
186