1*3e12c5d1SDavid du Colombier /* Common routines for _dtoa and strtod */
2*3e12c5d1SDavid du Colombier
3*3e12c5d1SDavid du Colombier #include "fconv.h"
4*3e12c5d1SDavid du Colombier
5*3e12c5d1SDavid du Colombier #ifdef DEBUG
6*3e12c5d1SDavid du Colombier #include <stdio.h>
7*3e12c5d1SDavid du Colombier #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
8*3e12c5d1SDavid du Colombier #endif
9*3e12c5d1SDavid du Colombier
10*3e12c5d1SDavid du Colombier double
11*3e12c5d1SDavid du Colombier _tens[] = {
12*3e12c5d1SDavid du Colombier 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
13*3e12c5d1SDavid du Colombier 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
14*3e12c5d1SDavid du Colombier 1e20, 1e21, 1e22
15*3e12c5d1SDavid du Colombier #ifdef VAX
16*3e12c5d1SDavid du Colombier , 1e23, 1e24
17*3e12c5d1SDavid du Colombier #endif
18*3e12c5d1SDavid du Colombier };
19*3e12c5d1SDavid du Colombier
20*3e12c5d1SDavid du Colombier
21*3e12c5d1SDavid du Colombier #ifdef IEEE_Arith
22*3e12c5d1SDavid du Colombier double _bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
23*3e12c5d1SDavid du Colombier double _tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
24*3e12c5d1SDavid du Colombier #else
25*3e12c5d1SDavid du Colombier #ifdef IBM
26*3e12c5d1SDavid du Colombier double _bigtens[] = { 1e16, 1e32, 1e64 };
27*3e12c5d1SDavid du Colombier double _tinytens[] = { 1e-16, 1e-32, 1e-64 };
28*3e12c5d1SDavid du Colombier #else
29*3e12c5d1SDavid du Colombier double _bigtens[] = { 1e16, 1e32 };
30*3e12c5d1SDavid du Colombier double _tinytens[] = { 1e-16, 1e-32 };
31*3e12c5d1SDavid du Colombier #endif
32*3e12c5d1SDavid du Colombier #endif
33*3e12c5d1SDavid du Colombier
34*3e12c5d1SDavid du Colombier static Bigint *freelist[Kmax+1];
35*3e12c5d1SDavid du Colombier
36*3e12c5d1SDavid du Colombier Bigint *
_Balloc(int k)37*3e12c5d1SDavid du Colombier _Balloc(int k)
38*3e12c5d1SDavid du Colombier {
39*3e12c5d1SDavid du Colombier int x;
40*3e12c5d1SDavid du Colombier Bigint *rv;
41*3e12c5d1SDavid du Colombier
42*3e12c5d1SDavid du Colombier if (rv = freelist[k]) {
43*3e12c5d1SDavid du Colombier freelist[k] = rv->next;
44*3e12c5d1SDavid du Colombier }
45*3e12c5d1SDavid du Colombier else {
46*3e12c5d1SDavid du Colombier x = 1 << k;
47*3e12c5d1SDavid du Colombier rv = (Bigint *)malloc(sizeof(Bigint) + (x-1)*sizeof(long));
48*3e12c5d1SDavid du Colombier rv->k = k;
49*3e12c5d1SDavid du Colombier rv->maxwds = x;
50*3e12c5d1SDavid du Colombier }
51*3e12c5d1SDavid du Colombier rv->sign = rv->wds = 0;
52*3e12c5d1SDavid du Colombier return rv;
53*3e12c5d1SDavid du Colombier }
54*3e12c5d1SDavid du Colombier
55*3e12c5d1SDavid du Colombier void
_Bfree(Bigint * v)56*3e12c5d1SDavid du Colombier _Bfree(Bigint *v)
57*3e12c5d1SDavid du Colombier {
58*3e12c5d1SDavid du Colombier if (v) {
59*3e12c5d1SDavid du Colombier v->next = freelist[v->k];
60*3e12c5d1SDavid du Colombier freelist[v->k] = v;
61*3e12c5d1SDavid du Colombier }
62*3e12c5d1SDavid du Colombier }
63*3e12c5d1SDavid du Colombier
64*3e12c5d1SDavid du Colombier
65*3e12c5d1SDavid du Colombier Bigint *
_multadd(Bigint * b,int m,int a)66*3e12c5d1SDavid du Colombier _multadd(Bigint *b, int m, int a) /* multiply by m and add a */
67*3e12c5d1SDavid du Colombier {
68*3e12c5d1SDavid du Colombier int i, wds;
69*3e12c5d1SDavid du Colombier unsigned long *x, y;
70*3e12c5d1SDavid du Colombier #ifdef Pack_32
71*3e12c5d1SDavid du Colombier unsigned long xi, z;
72*3e12c5d1SDavid du Colombier #endif
73*3e12c5d1SDavid du Colombier Bigint *b1;
74*3e12c5d1SDavid du Colombier
75*3e12c5d1SDavid du Colombier wds = b->wds;
76*3e12c5d1SDavid du Colombier x = b->x;
77*3e12c5d1SDavid du Colombier i = 0;
78*3e12c5d1SDavid du Colombier do {
79*3e12c5d1SDavid du Colombier #ifdef Pack_32
80*3e12c5d1SDavid du Colombier xi = *x;
81*3e12c5d1SDavid du Colombier y = (xi & 0xffff) * m + a;
82*3e12c5d1SDavid du Colombier z = (xi >> 16) * m + (y >> 16);
83*3e12c5d1SDavid du Colombier a = (int)(z >> 16);
84*3e12c5d1SDavid du Colombier *x++ = (z << 16) + (y & 0xffff);
85*3e12c5d1SDavid du Colombier #else
86*3e12c5d1SDavid du Colombier y = *x * m + a;
87*3e12c5d1SDavid du Colombier a = (int)(y >> 16);
88*3e12c5d1SDavid du Colombier *x++ = y & 0xffff;
89*3e12c5d1SDavid du Colombier #endif
90*3e12c5d1SDavid du Colombier }
91*3e12c5d1SDavid du Colombier while(++i < wds);
92*3e12c5d1SDavid du Colombier if (a) {
93*3e12c5d1SDavid du Colombier if (wds >= b->maxwds) {
94*3e12c5d1SDavid du Colombier b1 = Balloc(b->k+1);
95*3e12c5d1SDavid du Colombier Bcopy(b1, b);
96*3e12c5d1SDavid du Colombier Bfree(b);
97*3e12c5d1SDavid du Colombier b = b1;
98*3e12c5d1SDavid du Colombier }
99*3e12c5d1SDavid du Colombier b->x[wds++] = a;
100*3e12c5d1SDavid du Colombier b->wds = wds;
101*3e12c5d1SDavid du Colombier }
102*3e12c5d1SDavid du Colombier return b;
103*3e12c5d1SDavid du Colombier }
104*3e12c5d1SDavid du Colombier
105*3e12c5d1SDavid du Colombier int
_hi0bits(register unsigned long x)106*3e12c5d1SDavid du Colombier _hi0bits(register unsigned long x)
107*3e12c5d1SDavid du Colombier {
108*3e12c5d1SDavid du Colombier register int k = 0;
109*3e12c5d1SDavid du Colombier
110*3e12c5d1SDavid du Colombier if (!(x & 0xffff0000)) {
111*3e12c5d1SDavid du Colombier k = 16;
112*3e12c5d1SDavid du Colombier x <<= 16;
113*3e12c5d1SDavid du Colombier }
114*3e12c5d1SDavid du Colombier if (!(x & 0xff000000)) {
115*3e12c5d1SDavid du Colombier k += 8;
116*3e12c5d1SDavid du Colombier x <<= 8;
117*3e12c5d1SDavid du Colombier }
118*3e12c5d1SDavid du Colombier if (!(x & 0xf0000000)) {
119*3e12c5d1SDavid du Colombier k += 4;
120*3e12c5d1SDavid du Colombier x <<= 4;
121*3e12c5d1SDavid du Colombier }
122*3e12c5d1SDavid du Colombier if (!(x & 0xc0000000)) {
123*3e12c5d1SDavid du Colombier k += 2;
124*3e12c5d1SDavid du Colombier x <<= 2;
125*3e12c5d1SDavid du Colombier }
126*3e12c5d1SDavid du Colombier if (!(x & 0x80000000)) {
127*3e12c5d1SDavid du Colombier k++;
128*3e12c5d1SDavid du Colombier if (!(x & 0x40000000))
129*3e12c5d1SDavid du Colombier return 32;
130*3e12c5d1SDavid du Colombier }
131*3e12c5d1SDavid du Colombier return k;
132*3e12c5d1SDavid du Colombier }
133*3e12c5d1SDavid du Colombier
134*3e12c5d1SDavid du Colombier static int
lo0bits(unsigned long * y)135*3e12c5d1SDavid du Colombier lo0bits(unsigned long *y)
136*3e12c5d1SDavid du Colombier {
137*3e12c5d1SDavid du Colombier register int k;
138*3e12c5d1SDavid du Colombier register unsigned long x = *y;
139*3e12c5d1SDavid du Colombier
140*3e12c5d1SDavid du Colombier if (x & 7) {
141*3e12c5d1SDavid du Colombier if (x & 1)
142*3e12c5d1SDavid du Colombier return 0;
143*3e12c5d1SDavid du Colombier if (x & 2) {
144*3e12c5d1SDavid du Colombier *y = x >> 1;
145*3e12c5d1SDavid du Colombier return 1;
146*3e12c5d1SDavid du Colombier }
147*3e12c5d1SDavid du Colombier *y = x >> 2;
148*3e12c5d1SDavid du Colombier return 2;
149*3e12c5d1SDavid du Colombier }
150*3e12c5d1SDavid du Colombier k = 0;
151*3e12c5d1SDavid du Colombier if (!(x & 0xffff)) {
152*3e12c5d1SDavid du Colombier k = 16;
153*3e12c5d1SDavid du Colombier x >>= 16;
154*3e12c5d1SDavid du Colombier }
155*3e12c5d1SDavid du Colombier if (!(x & 0xff)) {
156*3e12c5d1SDavid du Colombier k += 8;
157*3e12c5d1SDavid du Colombier x >>= 8;
158*3e12c5d1SDavid du Colombier }
159*3e12c5d1SDavid du Colombier if (!(x & 0xf)) {
160*3e12c5d1SDavid du Colombier k += 4;
161*3e12c5d1SDavid du Colombier x >>= 4;
162*3e12c5d1SDavid du Colombier }
163*3e12c5d1SDavid du Colombier if (!(x & 0x3)) {
164*3e12c5d1SDavid du Colombier k += 2;
165*3e12c5d1SDavid du Colombier x >>= 2;
166*3e12c5d1SDavid du Colombier }
167*3e12c5d1SDavid du Colombier if (!(x & 1)) {
168*3e12c5d1SDavid du Colombier k++;
169*3e12c5d1SDavid du Colombier x >>= 1;
170*3e12c5d1SDavid du Colombier if (!x & 1)
171*3e12c5d1SDavid du Colombier return 32;
172*3e12c5d1SDavid du Colombier }
173*3e12c5d1SDavid du Colombier *y = x;
174*3e12c5d1SDavid du Colombier return k;
175*3e12c5d1SDavid du Colombier }
176*3e12c5d1SDavid du Colombier
177*3e12c5d1SDavid du Colombier Bigint *
_i2b(int i)178*3e12c5d1SDavid du Colombier _i2b(int i)
179*3e12c5d1SDavid du Colombier {
180*3e12c5d1SDavid du Colombier Bigint *b;
181*3e12c5d1SDavid du Colombier
182*3e12c5d1SDavid du Colombier b = Balloc(1);
183*3e12c5d1SDavid du Colombier b->x[0] = i;
184*3e12c5d1SDavid du Colombier b->wds = 1;
185*3e12c5d1SDavid du Colombier return b;
186*3e12c5d1SDavid du Colombier }
187*3e12c5d1SDavid du Colombier
188*3e12c5d1SDavid du Colombier Bigint *
_mult(Bigint * a,Bigint * b)189*3e12c5d1SDavid du Colombier _mult(Bigint *a, Bigint *b)
190*3e12c5d1SDavid du Colombier {
191*3e12c5d1SDavid du Colombier Bigint *c;
192*3e12c5d1SDavid du Colombier int k, wa, wb, wc;
193*3e12c5d1SDavid du Colombier unsigned long carry, y, z;
194*3e12c5d1SDavid du Colombier unsigned long *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
195*3e12c5d1SDavid du Colombier #ifdef Pack_32
196*3e12c5d1SDavid du Colombier unsigned long z2;
197*3e12c5d1SDavid du Colombier #endif
198*3e12c5d1SDavid du Colombier
199*3e12c5d1SDavid du Colombier if (a->wds < b->wds) {
200*3e12c5d1SDavid du Colombier c = a;
201*3e12c5d1SDavid du Colombier a = b;
202*3e12c5d1SDavid du Colombier b = c;
203*3e12c5d1SDavid du Colombier }
204*3e12c5d1SDavid du Colombier k = a->k;
205*3e12c5d1SDavid du Colombier wa = a->wds;
206*3e12c5d1SDavid du Colombier wb = b->wds;
207*3e12c5d1SDavid du Colombier wc = wa + wb;
208*3e12c5d1SDavid du Colombier if (wc > a->maxwds)
209*3e12c5d1SDavid du Colombier k++;
210*3e12c5d1SDavid du Colombier c = Balloc(k);
211*3e12c5d1SDavid du Colombier for(x = c->x, xa = x + wc; x < xa; x++)
212*3e12c5d1SDavid du Colombier *x = 0;
213*3e12c5d1SDavid du Colombier xa = a->x;
214*3e12c5d1SDavid du Colombier xae = xa + wa;
215*3e12c5d1SDavid du Colombier xb = b->x;
216*3e12c5d1SDavid du Colombier xbe = xb + wb;
217*3e12c5d1SDavid du Colombier xc0 = c->x;
218*3e12c5d1SDavid du Colombier #ifdef Pack_32
219*3e12c5d1SDavid du Colombier for(; xb < xbe; xb++, xc0++) {
220*3e12c5d1SDavid du Colombier if (y = *xb & 0xffff) {
221*3e12c5d1SDavid du Colombier x = xa;
222*3e12c5d1SDavid du Colombier xc = xc0;
223*3e12c5d1SDavid du Colombier carry = 0;
224*3e12c5d1SDavid du Colombier do {
225*3e12c5d1SDavid du Colombier z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
226*3e12c5d1SDavid du Colombier carry = z >> 16;
227*3e12c5d1SDavid du Colombier z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
228*3e12c5d1SDavid du Colombier carry = z2 >> 16;
229*3e12c5d1SDavid du Colombier Storeinc(xc, z2, z);
230*3e12c5d1SDavid du Colombier }
231*3e12c5d1SDavid du Colombier while(x < xae);
232*3e12c5d1SDavid du Colombier *xc = carry;
233*3e12c5d1SDavid du Colombier }
234*3e12c5d1SDavid du Colombier if (y = *xb >> 16) {
235*3e12c5d1SDavid du Colombier x = xa;
236*3e12c5d1SDavid du Colombier xc = xc0;
237*3e12c5d1SDavid du Colombier carry = 0;
238*3e12c5d1SDavid du Colombier z2 = *xc;
239*3e12c5d1SDavid du Colombier do {
240*3e12c5d1SDavid du Colombier z = (*x & 0xffff) * y + (*xc >> 16) + carry;
241*3e12c5d1SDavid du Colombier carry = z >> 16;
242*3e12c5d1SDavid du Colombier Storeinc(xc, z, z2);
243*3e12c5d1SDavid du Colombier z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
244*3e12c5d1SDavid du Colombier carry = z2 >> 16;
245*3e12c5d1SDavid du Colombier }
246*3e12c5d1SDavid du Colombier while(x < xae);
247*3e12c5d1SDavid du Colombier *xc = z2;
248*3e12c5d1SDavid du Colombier }
249*3e12c5d1SDavid du Colombier }
250*3e12c5d1SDavid du Colombier #else
251*3e12c5d1SDavid du Colombier for(; xb < xbe; xc0++) {
252*3e12c5d1SDavid du Colombier if (y = *xb++) {
253*3e12c5d1SDavid du Colombier x = xa;
254*3e12c5d1SDavid du Colombier xc = xc0;
255*3e12c5d1SDavid du Colombier carry = 0;
256*3e12c5d1SDavid du Colombier do {
257*3e12c5d1SDavid du Colombier z = *x++ * y + *xc + carry;
258*3e12c5d1SDavid du Colombier carry = z >> 16;
259*3e12c5d1SDavid du Colombier *xc++ = z & 0xffff;
260*3e12c5d1SDavid du Colombier }
261*3e12c5d1SDavid du Colombier while(x < xae);
262*3e12c5d1SDavid du Colombier *xc = carry;
263*3e12c5d1SDavid du Colombier }
264*3e12c5d1SDavid du Colombier }
265*3e12c5d1SDavid du Colombier #endif
266*3e12c5d1SDavid du Colombier for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
267*3e12c5d1SDavid du Colombier c->wds = wc;
268*3e12c5d1SDavid du Colombier return c;
269*3e12c5d1SDavid du Colombier }
270*3e12c5d1SDavid du Colombier
271*3e12c5d1SDavid du Colombier static Bigint *p5s;
272*3e12c5d1SDavid du Colombier
273*3e12c5d1SDavid du Colombier Bigint *
_pow5mult(Bigint * b,int k)274*3e12c5d1SDavid du Colombier _pow5mult(Bigint *b, int k)
275*3e12c5d1SDavid du Colombier {
276*3e12c5d1SDavid du Colombier Bigint *b1, *p5, *p51;
277*3e12c5d1SDavid du Colombier int i;
278*3e12c5d1SDavid du Colombier static int p05[3] = { 5, 25, 125 };
279*3e12c5d1SDavid du Colombier
280*3e12c5d1SDavid du Colombier if (i = k & 3)
281*3e12c5d1SDavid du Colombier b = multadd(b, p05[i-1], 0);
282*3e12c5d1SDavid du Colombier
283*3e12c5d1SDavid du Colombier if (!(k >>= 2))
284*3e12c5d1SDavid du Colombier return b;
285*3e12c5d1SDavid du Colombier if (!(p5 = p5s)) {
286*3e12c5d1SDavid du Colombier /* first time */
287*3e12c5d1SDavid du Colombier p5 = p5s = i2b(625);
288*3e12c5d1SDavid du Colombier p5->next = 0;
289*3e12c5d1SDavid du Colombier }
290*3e12c5d1SDavid du Colombier for(;;) {
291*3e12c5d1SDavid du Colombier if (k & 1) {
292*3e12c5d1SDavid du Colombier b1 = mult(b, p5);
293*3e12c5d1SDavid du Colombier Bfree(b);
294*3e12c5d1SDavid du Colombier b = b1;
295*3e12c5d1SDavid du Colombier }
296*3e12c5d1SDavid du Colombier if (!(k >>= 1))
297*3e12c5d1SDavid du Colombier break;
298*3e12c5d1SDavid du Colombier if (!(p51 = p5->next)) {
299*3e12c5d1SDavid du Colombier p51 = p5->next = mult(p5,p5);
300*3e12c5d1SDavid du Colombier p51->next = 0;
301*3e12c5d1SDavid du Colombier }
302*3e12c5d1SDavid du Colombier p5 = p51;
303*3e12c5d1SDavid du Colombier }
304*3e12c5d1SDavid du Colombier return b;
305*3e12c5d1SDavid du Colombier }
306*3e12c5d1SDavid du Colombier
307*3e12c5d1SDavid du Colombier Bigint *
_lshift(Bigint * b,int k)308*3e12c5d1SDavid du Colombier _lshift(Bigint *b, int k)
309*3e12c5d1SDavid du Colombier {
310*3e12c5d1SDavid du Colombier int i, k1, n, n1;
311*3e12c5d1SDavid du Colombier Bigint *b1;
312*3e12c5d1SDavid du Colombier unsigned long *x, *x1, *xe, z;
313*3e12c5d1SDavid du Colombier
314*3e12c5d1SDavid du Colombier #ifdef Pack_32
315*3e12c5d1SDavid du Colombier n = k >> 5;
316*3e12c5d1SDavid du Colombier #else
317*3e12c5d1SDavid du Colombier n = k >> 4;
318*3e12c5d1SDavid du Colombier #endif
319*3e12c5d1SDavid du Colombier k1 = b->k;
320*3e12c5d1SDavid du Colombier n1 = n + b->wds + 1;
321*3e12c5d1SDavid du Colombier for(i = b->maxwds; n1 > i; i <<= 1)
322*3e12c5d1SDavid du Colombier k1++;
323*3e12c5d1SDavid du Colombier b1 = Balloc(k1);
324*3e12c5d1SDavid du Colombier x1 = b1->x;
325*3e12c5d1SDavid du Colombier for(i = 0; i < n; i++)
326*3e12c5d1SDavid du Colombier *x1++ = 0;
327*3e12c5d1SDavid du Colombier x = b->x;
328*3e12c5d1SDavid du Colombier xe = x + b->wds;
329*3e12c5d1SDavid du Colombier #ifdef Pack_32
330*3e12c5d1SDavid du Colombier if (k &= 0x1f) {
331*3e12c5d1SDavid du Colombier k1 = 32 - k;
332*3e12c5d1SDavid du Colombier z = 0;
333*3e12c5d1SDavid du Colombier do {
334*3e12c5d1SDavid du Colombier *x1++ = *x << k | z;
335*3e12c5d1SDavid du Colombier z = *x++ >> k1;
336*3e12c5d1SDavid du Colombier }
337*3e12c5d1SDavid du Colombier while(x < xe);
338*3e12c5d1SDavid du Colombier if (*x1 = z)
339*3e12c5d1SDavid du Colombier ++n1;
340*3e12c5d1SDavid du Colombier }
341*3e12c5d1SDavid du Colombier #else
342*3e12c5d1SDavid du Colombier if (k &= 0xf) {
343*3e12c5d1SDavid du Colombier k1 = 16 - k;
344*3e12c5d1SDavid du Colombier z = 0;
345*3e12c5d1SDavid du Colombier do {
346*3e12c5d1SDavid du Colombier *x1++ = *x << k & 0xffff | z;
347*3e12c5d1SDavid du Colombier z = *x++ >> k1;
348*3e12c5d1SDavid du Colombier }
349*3e12c5d1SDavid du Colombier while(x < xe);
350*3e12c5d1SDavid du Colombier if (*x1 = z)
351*3e12c5d1SDavid du Colombier ++n1;
352*3e12c5d1SDavid du Colombier }
353*3e12c5d1SDavid du Colombier #endif
354*3e12c5d1SDavid du Colombier else do
355*3e12c5d1SDavid du Colombier *x1++ = *x++;
356*3e12c5d1SDavid du Colombier while(x < xe);
357*3e12c5d1SDavid du Colombier b1->wds = n1 - 1;
358*3e12c5d1SDavid du Colombier Bfree(b);
359*3e12c5d1SDavid du Colombier return b1;
360*3e12c5d1SDavid du Colombier }
361*3e12c5d1SDavid du Colombier
362*3e12c5d1SDavid du Colombier int
_cmp(Bigint * a,Bigint * b)363*3e12c5d1SDavid du Colombier _cmp(Bigint *a, Bigint *b)
364*3e12c5d1SDavid du Colombier {
365*3e12c5d1SDavid du Colombier unsigned long *xa, *xa0, *xb, *xb0;
366*3e12c5d1SDavid du Colombier int i, j;
367*3e12c5d1SDavid du Colombier
368*3e12c5d1SDavid du Colombier i = a->wds;
369*3e12c5d1SDavid du Colombier j = b->wds;
370*3e12c5d1SDavid du Colombier #ifdef DEBUG
371*3e12c5d1SDavid du Colombier if (i > 1 && !a->x[i-1])
372*3e12c5d1SDavid du Colombier Bug("cmp called with a->x[a->wds-1] == 0");
373*3e12c5d1SDavid du Colombier if (j > 1 && !b->x[j-1])
374*3e12c5d1SDavid du Colombier Bug("cmp called with b->x[b->wds-1] == 0");
375*3e12c5d1SDavid du Colombier #endif
376*3e12c5d1SDavid du Colombier if (i -= j)
377*3e12c5d1SDavid du Colombier return i;
378*3e12c5d1SDavid du Colombier xa0 = a->x;
379*3e12c5d1SDavid du Colombier xa = xa0 + j;
380*3e12c5d1SDavid du Colombier xb0 = b->x;
381*3e12c5d1SDavid du Colombier xb = xb0 + j;
382*3e12c5d1SDavid du Colombier for(;;) {
383*3e12c5d1SDavid du Colombier if (*--xa != *--xb)
384*3e12c5d1SDavid du Colombier return *xa < *xb ? -1 : 1;
385*3e12c5d1SDavid du Colombier if (xa <= xa0)
386*3e12c5d1SDavid du Colombier break;
387*3e12c5d1SDavid du Colombier }
388*3e12c5d1SDavid du Colombier return 0;
389*3e12c5d1SDavid du Colombier }
390*3e12c5d1SDavid du Colombier
391*3e12c5d1SDavid du Colombier Bigint *
_diff(Bigint * a,Bigint * b)392*3e12c5d1SDavid du Colombier _diff(Bigint *a, Bigint *b)
393*3e12c5d1SDavid du Colombier {
394*3e12c5d1SDavid du Colombier Bigint *c;
395*3e12c5d1SDavid du Colombier int i, wa, wb;
396*3e12c5d1SDavid du Colombier long borrow, y; /* We need signed shifts here. */
397*3e12c5d1SDavid du Colombier unsigned long *xa, *xae, *xb, *xbe, *xc;
398*3e12c5d1SDavid du Colombier #ifdef Pack_32
399*3e12c5d1SDavid du Colombier long z;
400*3e12c5d1SDavid du Colombier #endif
401*3e12c5d1SDavid du Colombier
402*3e12c5d1SDavid du Colombier i = cmp(a,b);
403*3e12c5d1SDavid du Colombier if (!i) {
404*3e12c5d1SDavid du Colombier c = Balloc(0);
405*3e12c5d1SDavid du Colombier c->wds = 1;
406*3e12c5d1SDavid du Colombier c->x[0] = 0;
407*3e12c5d1SDavid du Colombier return c;
408*3e12c5d1SDavid du Colombier }
409*3e12c5d1SDavid du Colombier if (i < 0) {
410*3e12c5d1SDavid du Colombier c = a;
411*3e12c5d1SDavid du Colombier a = b;
412*3e12c5d1SDavid du Colombier b = c;
413*3e12c5d1SDavid du Colombier i = 1;
414*3e12c5d1SDavid du Colombier }
415*3e12c5d1SDavid du Colombier else
416*3e12c5d1SDavid du Colombier i = 0;
417*3e12c5d1SDavid du Colombier c = Balloc(a->k);
418*3e12c5d1SDavid du Colombier c->sign = i;
419*3e12c5d1SDavid du Colombier wa = a->wds;
420*3e12c5d1SDavid du Colombier xa = a->x;
421*3e12c5d1SDavid du Colombier xae = xa + wa;
422*3e12c5d1SDavid du Colombier wb = b->wds;
423*3e12c5d1SDavid du Colombier xb = b->x;
424*3e12c5d1SDavid du Colombier xbe = xb + wb;
425*3e12c5d1SDavid du Colombier xc = c->x;
426*3e12c5d1SDavid du Colombier borrow = 0;
427*3e12c5d1SDavid du Colombier #ifdef Pack_32
428*3e12c5d1SDavid du Colombier do {
429*3e12c5d1SDavid du Colombier y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
430*3e12c5d1SDavid du Colombier borrow = y >> 16;
431*3e12c5d1SDavid du Colombier Sign_Extend(borrow, y);
432*3e12c5d1SDavid du Colombier z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
433*3e12c5d1SDavid du Colombier borrow = z >> 16;
434*3e12c5d1SDavid du Colombier Sign_Extend(borrow, z);
435*3e12c5d1SDavid du Colombier Storeinc(xc, z, y);
436*3e12c5d1SDavid du Colombier }
437*3e12c5d1SDavid du Colombier while(xb < xbe);
438*3e12c5d1SDavid du Colombier while(xa < xae) {
439*3e12c5d1SDavid du Colombier y = (*xa & 0xffff) + borrow;
440*3e12c5d1SDavid du Colombier borrow = y >> 16;
441*3e12c5d1SDavid du Colombier Sign_Extend(borrow, y);
442*3e12c5d1SDavid du Colombier z = (*xa++ >> 16) + borrow;
443*3e12c5d1SDavid du Colombier borrow = z >> 16;
444*3e12c5d1SDavid du Colombier Sign_Extend(borrow, z);
445*3e12c5d1SDavid du Colombier Storeinc(xc, z, y);
446*3e12c5d1SDavid du Colombier }
447*3e12c5d1SDavid du Colombier #else
448*3e12c5d1SDavid du Colombier do {
449*3e12c5d1SDavid du Colombier y = *xa++ - *xb++ + borrow;
450*3e12c5d1SDavid du Colombier borrow = y >> 16;
451*3e12c5d1SDavid du Colombier Sign_Extend(borrow, y);
452*3e12c5d1SDavid du Colombier *xc++ = y & 0xffff;
453*3e12c5d1SDavid du Colombier }
454*3e12c5d1SDavid du Colombier while(xb < xbe);
455*3e12c5d1SDavid du Colombier while(xa < xae) {
456*3e12c5d1SDavid du Colombier y = *xa++ + borrow;
457*3e12c5d1SDavid du Colombier borrow = y >> 16;
458*3e12c5d1SDavid du Colombier Sign_Extend(borrow, y);
459*3e12c5d1SDavid du Colombier *xc++ = y & 0xffff;
460*3e12c5d1SDavid du Colombier }
461*3e12c5d1SDavid du Colombier #endif
462*3e12c5d1SDavid du Colombier while(!*--xc)
463*3e12c5d1SDavid du Colombier wa--;
464*3e12c5d1SDavid du Colombier c->wds = wa;
465*3e12c5d1SDavid du Colombier return c;
466*3e12c5d1SDavid du Colombier }
467*3e12c5d1SDavid du Colombier
468*3e12c5d1SDavid du Colombier Bigint *
_d2b(double darg,int * e,int * bits)469*3e12c5d1SDavid du Colombier _d2b(double darg, int *e, int *bits)
470*3e12c5d1SDavid du Colombier {
471*3e12c5d1SDavid du Colombier Bigint *b;
472*3e12c5d1SDavid du Colombier int de, i, k;
473*3e12c5d1SDavid du Colombier unsigned long *x, y, z;
474*3e12c5d1SDavid du Colombier Dul d;
475*3e12c5d1SDavid du Colombier #ifdef VAX
476*3e12c5d1SDavid du Colombier unsigned long d0, d1;
477*3e12c5d1SDavid du Colombier d.d = darg;
478*3e12c5d1SDavid du Colombier d0 = word0(d) >> 16 | word0(d) << 16;
479*3e12c5d1SDavid du Colombier d1 = word1(d) >> 16 | word1(d) << 16;
480*3e12c5d1SDavid du Colombier #else
481*3e12c5d1SDavid du Colombier d.d = darg;
482*3e12c5d1SDavid du Colombier #define d0 word0(d)
483*3e12c5d1SDavid du Colombier #define d1 word1(d)
484*3e12c5d1SDavid du Colombier #endif
485*3e12c5d1SDavid du Colombier
486*3e12c5d1SDavid du Colombier #ifdef Pack_32
487*3e12c5d1SDavid du Colombier b = Balloc(1);
488*3e12c5d1SDavid du Colombier #else
489*3e12c5d1SDavid du Colombier b = Balloc(2);
490*3e12c5d1SDavid du Colombier #endif
491*3e12c5d1SDavid du Colombier x = b->x;
492*3e12c5d1SDavid du Colombier
493*3e12c5d1SDavid du Colombier z = d0 & Frac_mask;
494*3e12c5d1SDavid du Colombier d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
495*3e12c5d1SDavid du Colombier #ifdef Sudden_Underflow
496*3e12c5d1SDavid du Colombier de = (int)(d0 >> Exp_shift);
497*3e12c5d1SDavid du Colombier #ifndef IBM
498*3e12c5d1SDavid du Colombier z |= Exp_msk11;
499*3e12c5d1SDavid du Colombier #endif
500*3e12c5d1SDavid du Colombier #else
501*3e12c5d1SDavid du Colombier if (de = (int)(d0 >> Exp_shift))
502*3e12c5d1SDavid du Colombier z |= Exp_msk1;
503*3e12c5d1SDavid du Colombier #endif
504*3e12c5d1SDavid du Colombier #ifdef Pack_32
505*3e12c5d1SDavid du Colombier if (y = d1) {
506*3e12c5d1SDavid du Colombier if (k = lo0bits(&y)) {
507*3e12c5d1SDavid du Colombier x[0] = y | z << 32 - k;
508*3e12c5d1SDavid du Colombier z >>= k;
509*3e12c5d1SDavid du Colombier }
510*3e12c5d1SDavid du Colombier else
511*3e12c5d1SDavid du Colombier x[0] = y;
512*3e12c5d1SDavid du Colombier i = b->wds = (x[1] = z) ? 2 : 1;
513*3e12c5d1SDavid du Colombier }
514*3e12c5d1SDavid du Colombier else {
515*3e12c5d1SDavid du Colombier #ifdef DEBUG
516*3e12c5d1SDavid du Colombier if (!z)
517*3e12c5d1SDavid du Colombier Bug("Zero passed to d2b");
518*3e12c5d1SDavid du Colombier #endif
519*3e12c5d1SDavid du Colombier k = lo0bits(&z);
520*3e12c5d1SDavid du Colombier x[0] = z;
521*3e12c5d1SDavid du Colombier i = b->wds = 1;
522*3e12c5d1SDavid du Colombier k += 32;
523*3e12c5d1SDavid du Colombier }
524*3e12c5d1SDavid du Colombier #else
525*3e12c5d1SDavid du Colombier if (y = d1) {
526*3e12c5d1SDavid du Colombier if (k = lo0bits(&y))
527*3e12c5d1SDavid du Colombier if (k >= 16) {
528*3e12c5d1SDavid du Colombier x[0] = y | z << 32 - k & 0xffff;
529*3e12c5d1SDavid du Colombier x[1] = z >> k - 16 & 0xffff;
530*3e12c5d1SDavid du Colombier x[2] = z >> k;
531*3e12c5d1SDavid du Colombier i = 2;
532*3e12c5d1SDavid du Colombier }
533*3e12c5d1SDavid du Colombier else {
534*3e12c5d1SDavid du Colombier x[0] = y & 0xffff;
535*3e12c5d1SDavid du Colombier x[1] = y >> 16 | z << 16 - k & 0xffff;
536*3e12c5d1SDavid du Colombier x[2] = z >> k & 0xffff;
537*3e12c5d1SDavid du Colombier x[3] = z >> k+16;
538*3e12c5d1SDavid du Colombier i = 3;
539*3e12c5d1SDavid du Colombier }
540*3e12c5d1SDavid du Colombier else {
541*3e12c5d1SDavid du Colombier x[0] = y & 0xffff;
542*3e12c5d1SDavid du Colombier x[1] = y >> 16;
543*3e12c5d1SDavid du Colombier x[2] = z & 0xffff;
544*3e12c5d1SDavid du Colombier x[3] = z >> 16;
545*3e12c5d1SDavid du Colombier i = 3;
546*3e12c5d1SDavid du Colombier }
547*3e12c5d1SDavid du Colombier }
548*3e12c5d1SDavid du Colombier else {
549*3e12c5d1SDavid du Colombier #ifdef DEBUG
550*3e12c5d1SDavid du Colombier if (!z)
551*3e12c5d1SDavid du Colombier Bug("Zero passed to d2b");
552*3e12c5d1SDavid du Colombier #endif
553*3e12c5d1SDavid du Colombier k = lo0bits(&z);
554*3e12c5d1SDavid du Colombier if (k >= 16) {
555*3e12c5d1SDavid du Colombier x[0] = z;
556*3e12c5d1SDavid du Colombier i = 0;
557*3e12c5d1SDavid du Colombier }
558*3e12c5d1SDavid du Colombier else {
559*3e12c5d1SDavid du Colombier x[0] = z & 0xffff;
560*3e12c5d1SDavid du Colombier x[1] = z >> 16;
561*3e12c5d1SDavid du Colombier i = 1;
562*3e12c5d1SDavid du Colombier }
563*3e12c5d1SDavid du Colombier k += 32;
564*3e12c5d1SDavid du Colombier }
565*3e12c5d1SDavid du Colombier while(!x[i])
566*3e12c5d1SDavid du Colombier --i;
567*3e12c5d1SDavid du Colombier b->wds = i + 1;
568*3e12c5d1SDavid du Colombier #endif
569*3e12c5d1SDavid du Colombier #ifndef Sudden_Underflow
570*3e12c5d1SDavid du Colombier if (de) {
571*3e12c5d1SDavid du Colombier #endif
572*3e12c5d1SDavid du Colombier #ifdef IBM
573*3e12c5d1SDavid du Colombier *e = (de - Bias - (P-1) << 2) + k;
574*3e12c5d1SDavid du Colombier *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
575*3e12c5d1SDavid du Colombier #else
576*3e12c5d1SDavid du Colombier *e = de - Bias - (P-1) + k;
577*3e12c5d1SDavid du Colombier *bits = P - k;
578*3e12c5d1SDavid du Colombier #endif
579*3e12c5d1SDavid du Colombier #ifndef Sudden_Underflow
580*3e12c5d1SDavid du Colombier }
581*3e12c5d1SDavid du Colombier else {
582*3e12c5d1SDavid du Colombier *e = de - Bias - (P-1) + 1 + k;
583*3e12c5d1SDavid du Colombier #ifdef Pack_32
584*3e12c5d1SDavid du Colombier *bits = 32*i - hi0bits(x[i-1]);
585*3e12c5d1SDavid du Colombier #else
586*3e12c5d1SDavid du Colombier *bits = (i+2)*16 - hi0bits(x[i]);
587*3e12c5d1SDavid du Colombier #endif
588*3e12c5d1SDavid du Colombier }
589*3e12c5d1SDavid du Colombier #endif
590*3e12c5d1SDavid du Colombier return b;
591*3e12c5d1SDavid du Colombier }
592*3e12c5d1SDavid du Colombier #undef d0
593*3e12c5d1SDavid du Colombier #undef d1
594