Contiki 2.5
small_mprec.c
1 /****************************************************************
2  *
3  * The author of this software is David M. Gay.
4  *
5  * Copyright (c) 1991 by AT&T.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose without fee is hereby granted, provided that this entire notice
9  * is included in all copies of any software which is or includes a copy
10  * or modification of this software and in all copies of the supporting
11  * documentation for such software.
12  *
13  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
14  * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
15  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
16  * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
17  *
18  ***************************************************************/
19 
20 /* Please send bug reports to
21  David M. Gay
22  AT&T Bell Laboratories, Room 2C-463
23  600 Mountain Avenue
24  Murray Hill, NJ 07974-2070
25  U.S.A.
26  dmg@research.att.com or research!dmg
27  */
28 
29 /* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
30  *
31  * This strtod returns a nearest machine number to the input decimal
32  * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
33  * broken by the IEEE round-even rule. Otherwise ties are broken by
34  * biased rounding (add half and chop).
35  *
36  * Inspired loosely by William D. Clinger's paper "How to Read Floating
37  * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
38  *
39  * Modifications:
40  *
41  * 1. We only require IEEE, IBM, or VAX double-precision
42  * arithmetic (not IEEE double-extended).
43  * 2. We get by with floating-point arithmetic in a case that
44  * Clinger missed -- when we're computing d * 10^n
45  * for a small integer d and the integer n is not too
46  * much larger than 22 (the maximum integer k for which
47  * we can represent 10^k exactly), we may be able to
48  * compute (d*10^k) * 10^(e-k) with just one roundoff.
49  * 3. Rather than a bit-at-a-time adjustment of the binary
50  * result in the hard case, we use floating-point
51  * arithmetic to determine the adjustment to within
52  * one bit; only in really hard cases do we need to
53  * compute a second residual.
54  * 4. Because of 3., we don't need a large table of powers of 10
55  * for ten-to-e (just some small tables, e.g. of 10^k
56  * for 0 <= k <= 22).
57  */
58 
59 /*
60  * #define IEEE_8087 for IEEE-arithmetic machines where the least
61  * significant byte has the lowest address.
62  * #define IEEE_MC68k for IEEE-arithmetic machines where the most
63  * significant byte has the lowest address.
64  * #define Sudden_Underflow for IEEE-format machines without gradual
65  * underflow (i.e., that flush to zero on underflow).
66  * #define IBM for IBM mainframe-style floating-point arithmetic.
67  * #define VAX for VAX-style floating-point arithmetic.
68  * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
69  * #define No_leftright to omit left-right logic in fast floating-point
70  * computation of dtoa.
71  * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
72  * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
73  * that use extended-precision instructions to compute rounded
74  * products and quotients) with IBM.
75  * #define ROUND_BIASED for IEEE-format with biased rounding.
76  * #define Inaccurate_Divide for IEEE-format with correctly rounded
77  * products but inaccurate quotients, e.g., for Intel i860.
78  * #define Just_16 to store 16 bits per 32-bit long when doing high-precision
79  * integer arithmetic. Whether this speeds things up or slows things
80  * down depends on the machine and the number being converted.
81  */
82 
83 
84 
85 #include <_ansi.h>
86 #include <stdlib.h>
87 #include <string.h>
88 #include <reent.h>
89 #include "small_mprec.h"
90 
91 /* reent.c knows this value */
92 #define _Kmax 15
93 
94 #if defined (_SMALL_PRINTF) || defined(SMALL_SCANF)
95 #define SMALL_LIB
96 #else
97 #define FULL_LIB
98 #endif
99 
100 /* SMALL_LIB is only defined if _SMALL_PRINTF or SMALL_SCANF have been defined
101  * which means that if you do only specified _SMALL_PRINTF and not SMALL_SCANF
102  * optimization about call of balloc in small_dtoa_r.c or smal_strtod.c will be
103  * performed for both printf and scanf
104  */
105 
106 
107 
108 #ifdef FULL_LIB
109 
110 
111 
112 _Bigint *
113 _DEFUN (Balloc, (ptr, k), struct _reent *ptr _AND int k)
114 {
115  int x;
116  _Bigint *rv ;
117 
118  _REENT_CHECK_MP(ptr);
119  if (_REENT_MP_FREELIST(ptr) == NULL)
120  {
121  /* Allocate a list of pointers to the mprec objects */
122  _REENT_MP_FREELIST(ptr) = (struct _Bigint **) _calloc_r (ptr,
123  sizeof (struct _Bigint *),
124  _Kmax + 1);
125  if (_REENT_MP_FREELIST(ptr) == NULL)
126  {
127  return NULL;
128  }
129  }
130 
131  if ((rv = _REENT_MP_FREELIST(ptr)[k]) != 0)
132  {
133  _REENT_MP_FREELIST(ptr)[k] = rv->_next;
134  }
135  else
136  {
137  x = 1 << k;
138  /* Allocate an mprec Bigint and stick in in the freelist */
139  rv = (_Bigint *) _calloc_r (ptr,
140  1,
141  sizeof (_Bigint) +
142  (x-1) * sizeof(rv->_x));
143  if (rv == NULL) return NULL;
144  rv->_k = k;
145  rv->_maxwds = x;
146  }
147  rv->_sign = rv->_wds = 0;
148  return rv;
149 }
150 
151 void
152 _DEFUN (Bfree, (ptr, v), struct _reent *ptr _AND _Bigint * v)
153 {
154  _REENT_CHECK_MP(ptr);
155  if (v)
156  {
157  v->_next = _REENT_MP_FREELIST(ptr)[v->_k];
158  _REENT_MP_FREELIST(ptr)[v->_k] = v;
159  }
160 }
161 
162 
163 _Bigint *
164 _DEFUN (multadd, (ptr, b, m, a),
165  struct _reent *ptr _AND
166  _Bigint * b _AND
167  int m _AND
168  int a)
169 {
170  int i, wds;
171  __ULong *x, y;
172 #ifdef Pack_32
173  __ULong xi, z;
174 #endif
175  _Bigint *b1;
176 
177  wds = b->_wds;
178  x = b->_x;
179  i = 0;
180  do
181  {
182 #ifdef Pack_32
183  xi = *x;
184  y = (xi & 0xffff) * m + a;
185  z = (xi >> 16) * m + (y >> 16);
186  a = (int) (z >> 16);
187  *x++ = (z << 16) + (y & 0xffff);
188 #else
189  y = *x * m + a;
190  a = (int) (y >> 16);
191  *x++ = y & 0xffff;
192 #endif
193  }
194  while (++i < wds);
195  if (a)
196  {
197  if (wds >= b->_maxwds)
198  {
199  b1 = Balloc (ptr, b->_k + 1);
200  Bcopy (b1, b);
201  Bfree (ptr, b);
202  b = b1;
203  }
204  b->_x[wds++] = a;
205  b->_wds = wds;
206  }
207  return b;
208 }
209 
210 _Bigint *
211 _DEFUN (s2b, (ptr, s, nd0, nd, y9),
212  struct _reent * ptr _AND
213  _CONST char *s _AND
214  int nd0 _AND
215  int nd _AND
216  __ULong y9)
217 {
218  _Bigint *b;
219  int i, k;
220  __Long x, y;
221 
222  x = (nd + 8) / 9;
223  for (k = 0, y = 1; x > y; y <<= 1, k++);
224 #ifdef Pack_32
225  b = Balloc (ptr, k);
226  b->_x[0] = y9;
227  b->_wds = 1;
228 #else
229  b = Balloc (ptr, k + 1);
230  b->_x[0] = y9 & 0xffff;
231  b->_wds = (b->_x[1] = y9 >> 16) ? 2 : 1;
232 #endif
233 
234  i = 9;
235  if (9 < nd0)
236  {
237  s += 9;
238  do
239  b = multadd (ptr, b, 10, *s++ - '0');
240  while (++i < nd0);
241  s++;
242  }
243  else
244  s += 10;
245  for (; i < nd; i++)
246  b = multadd (ptr, b, 10, *s++ - '0');
247  return b;
248 }
249 
250 int
251 _DEFUN (hi0bits,
252  (x), register __ULong x)
253 {
254  register int k = 0;
255 
256  if (!(x & 0xffff0000))
257  {
258  k = 16;
259  x <<= 16;
260  }
261  if (!(x & 0xff000000))
262  {
263  k += 8;
264  x <<= 8;
265  }
266  if (!(x & 0xf0000000))
267  {
268  k += 4;
269  x <<= 4;
270  }
271  if (!(x & 0xc0000000))
272  {
273  k += 2;
274  x <<= 2;
275  }
276  if (!(x & 0x80000000))
277  {
278  k++;
279  if (!(x & 0x40000000))
280  return 32;
281  }
282  return k;
283 }
284 
285 int
286 _DEFUN (lo0bits, (y), __ULong *y)
287 {
288  register int k;
289  register __ULong x = *y;
290 
291  if (x & 7)
292  {
293  if (x & 1)
294  return 0;
295  if (x & 2)
296  {
297  *y = x >> 1;
298  return 1;
299  }
300  *y = x >> 2;
301  return 2;
302  }
303  k = 0;
304  if (!(x & 0xffff))
305  {
306  k = 16;
307  x >>= 16;
308  }
309  if (!(x & 0xff))
310  {
311  k += 8;
312  x >>= 8;
313  }
314  if (!(x & 0xf))
315  {
316  k += 4;
317  x >>= 4;
318  }
319  if (!(x & 0x3))
320  {
321  k += 2;
322  x >>= 2;
323  }
324  if (!(x & 1))
325  {
326  k++;
327  x >>= 1;
328  if (!x & 1)
329  return 32;
330  }
331  *y = x;
332  return k;
333 }
334 
335 _Bigint *
336 _DEFUN (i2b, (ptr, i), struct _reent * ptr _AND int i)
337 {
338  _Bigint *b;
339 
340  b = Balloc (ptr, 1);
341  b->_x[0] = i;
342  b->_wds = 1;
343  return b;
344 }
345 
346 _Bigint *
347 _DEFUN (mult, (ptr, a, b), struct _reent * ptr _AND _Bigint * a _AND _Bigint * b)
348 {
349  _Bigint *c;
350  int k, wa, wb, wc;
351  __ULong carry, y, z;
352  __ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
353 #ifdef Pack_32
354  __ULong z2;
355 #endif
356 
357  if (a->_wds < b->_wds)
358  {
359  c = a;
360  a = b;
361  b = c;
362  }
363  k = a->_k;
364  wa = a->_wds;
365  wb = b->_wds;
366  wc = wa + wb;
367  if (wc > a->_maxwds)
368  k++;
369  c = Balloc (ptr, k);
370  for (x = c->_x, xa = x + wc; x < xa; x++)
371  *x = 0;
372  xa = a->_x;
373  xae = xa + wa;
374  xb = b->_x;
375  xbe = xb + wb;
376  xc0 = c->_x;
377 #ifdef Pack_32
378  for (; xb < xbe; xb++, xc0++)
379  {
380  if ((y = *xb & 0xffff) != 0)
381  {
382  x = xa;
383  xc = xc0;
384  carry = 0;
385  do
386  {
387  z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
388  carry = z >> 16;
389  z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
390  carry = z2 >> 16;
391  Storeinc (xc, z2, z);
392  }
393  while (x < xae);
394  *xc = carry;
395  }
396  if ((y = *xb >> 16) != 0)
397  {
398  x = xa;
399  xc = xc0;
400  carry = 0;
401  z2 = *xc;
402  do
403  {
404  z = (*x & 0xffff) * y + (*xc >> 16) + carry;
405  carry = z >> 16;
406  Storeinc (xc, z, z2);
407  z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
408  carry = z2 >> 16;
409  }
410  while (x < xae);
411  *xc = z2;
412  }
413  }
414 #else
415  for (; xb < xbe; xc0++)
416  {
417  if (y = *xb++)
418  {
419  x = xa;
420  xc = xc0;
421  carry = 0;
422  do
423  {
424  z = *x++ * y + *xc + carry;
425  carry = z >> 16;
426  *xc++ = z & 0xffff;
427  }
428  while (x < xae);
429  *xc = carry;
430  }
431  }
432 #endif
433  for (xc0 = c->_x, xc = xc0 + wc; wc > 0 && !*--xc; --wc);
434  c->_wds = wc;
435  return c;
436 }
437 
438 _Bigint *
439 _DEFUN (pow5mult,
440  (ptr, b, k), struct _reent * ptr _AND _Bigint * b _AND int k)
441 {
442  _Bigint *b1, *p5, *p51;
443  int i;
444  static _CONST int p05[3] = {5, 25, 125};
445 
446  if ((i = k & 3) != 0)
447  b = multadd (ptr, b, p05[i - 1], 0);
448 
449  if (!(k >>= 2))
450  return b;
451  _REENT_CHECK_MP(ptr);
452  if (!(p5 = _REENT_MP_P5S(ptr)))
453  {
454  /* first time */
455  p5 = _REENT_MP_P5S(ptr) = i2b (ptr, 625);
456  p5->_next = 0;
457  }
458  for (;;)
459  {
460  if (k & 1)
461  {
462  b1 = mult (ptr, b, p5);
463  Bfree (ptr, b);
464  b = b1;
465  }
466  if (!(k >>= 1))
467  break;
468  if (!(p51 = p5->_next))
469  {
470  p51 = p5->_next = mult (ptr, p5, p5);
471  p51->_next = 0;
472  }
473  p5 = p51;
474  }
475  return b;
476 }
477 
478 _Bigint *
479 _DEFUN (lshift, (ptr, b, k), struct _reent * ptr _AND _Bigint * b _AND int k)
480 {
481  int i, k1, n, n1;
482  _Bigint *b1;
483  __ULong *x, *x1, *xe, z;
484 
485 #ifdef Pack_32
486  n = k >> 5;
487 #else
488  n = k >> 4;
489 #endif
490  k1 = b->_k;
491  n1 = n + b->_wds + 1;
492  for (i = b->_maxwds; n1 > i; i <<= 1)
493  k1++;
494  b1 = Balloc (ptr, k1);
495  x1 = b1->_x;
496  for (i = 0; i < n; i++)
497  *x1++ = 0;
498  x = b->_x;
499  xe = x + b->_wds;
500 #ifdef Pack_32
501  if (k &= 0x1f)
502  {
503  k1 = 32 - k;
504  z = 0;
505  do
506  {
507  *x1++ = *x << k | z;
508  z = *x++ >> k1;
509  }
510  while (x < xe);
511  if ((*x1 = z) != 0)
512  ++n1;
513  }
514 #else
515  if (k &= 0xf)
516  {
517  k1 = 16 - k;
518  z = 0;
519  do
520  {
521  *x1++ = *x << k & 0xffff | z;
522  z = *x++ >> k1;
523  }
524  while (x < xe);
525  if (*x1 = z)
526  ++n1;
527  }
528 #endif
529  else
530  do
531  *x1++ = *x++;
532  while (x < xe);
533  b1->_wds = n1 - 1;
534  Bfree (ptr, b);
535  return b1;
536 }
537 
538 int
539 _DEFUN (cmp, (a, b), _Bigint * a _AND _Bigint * b)
540 {
541  __ULong *xa, *xa0, *xb, *xb0;
542  int i, j;
543 
544  i = a->_wds;
545  j = b->_wds;
546 #ifdef DEBUG
547  if (i > 1 && !a->_x[i - 1])
548  Bug ("cmp called with a->_x[a->_wds-1] == 0");
549  if (j > 1 && !b->_x[j - 1])
550  Bug ("cmp called with b->_x[b->_wds-1] == 0");
551 #endif
552  if (i -= j)
553  return i;
554  xa0 = a->_x;
555  xa = xa0 + j;
556  xb0 = b->_x;
557  xb = xb0 + j;
558  for (;;)
559  {
560  if (*--xa != *--xb)
561  return *xa < *xb ? -1 : 1;
562  if (xa <= xa0)
563  break;
564  }
565  return 0;
566 }
567 
568 _Bigint *
569 _DEFUN (diff, (ptr, a, b), struct _reent * ptr _AND
570  _Bigint * a _AND _Bigint * b)
571 {
572  _Bigint *c;
573  int i, wa, wb;
574  __Long borrow, y; /* We need signed shifts here. */
575  __ULong *xa, *xae, *xb, *xbe, *xc;
576 #ifdef Pack_32
577  __Long z;
578 #endif
579 
580  i = cmp (a, b);
581  if (!i)
582  {
583  c = Balloc (ptr, 0);
584  c->_wds = 1;
585  c->_x[0] = 0;
586  return c;
587  }
588  if (i < 0)
589  {
590  c = a;
591  a = b;
592  b = c;
593  i = 1;
594  }
595  else
596  i = 0;
597  c = Balloc (ptr, a->_k);
598  c->_sign = i;
599  wa = a->_wds;
600  xa = a->_x;
601  xae = xa + wa;
602  wb = b->_wds;
603  xb = b->_x;
604  xbe = xb + wb;
605  xc = c->_x;
606  borrow = 0;
607 #ifdef Pack_32
608  do
609  {
610  y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
611  borrow = y >> 16;
612  Sign_Extend (borrow, y);
613  z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
614  borrow = z >> 16;
615  Sign_Extend (borrow, z);
616  Storeinc (xc, z, y);
617  }
618  while (xb < xbe);
619  while (xa < xae)
620  {
621  y = (*xa & 0xffff) + borrow;
622  borrow = y >> 16;
623  Sign_Extend (borrow, y);
624  z = (*xa++ >> 16) + borrow;
625  borrow = z >> 16;
626  Sign_Extend (borrow, z);
627  Storeinc (xc, z, y);
628  }
629 #else
630  do
631  {
632  y = *xa++ - *xb++ + borrow;
633  borrow = y >> 16;
634  Sign_Extend (borrow, y);
635  *xc++ = y & 0xffff;
636  }
637  while (xb < xbe);
638  while (xa < xae)
639  {
640  y = *xa++ + borrow;
641  borrow = y >> 16;
642  Sign_Extend (borrow, y);
643  *xc++ = y & 0xffff;
644  }
645 #endif
646  while (!*--xc)
647  wa--;
648  c->_wds = wa;
649  return c;
650 }
651 
652 double
653 _DEFUN (ulp, (_x), double _x)
654 {
655  union double_union x, a;
656  register __Long L;
657 
658  x.d = _x;
659 
660  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
661 #ifndef Sudden_Underflow
662  if (L > 0)
663  {
664 #endif
665 #ifdef IBM
666  L |= Exp_msk1 >> 4;
667 #endif
668  word0 (a) = L;
669 #ifndef _DOUBLE_IS_32BITS
670  word1 (a) = 0;
671 #endif
672 
673 #ifndef Sudden_Underflow
674  }
675  else
676  {
677  L = -L >> Exp_shift;
678  if (L < Exp_shift)
679  {
680  word0 (a) = 0x80000 >> L;
681 #ifndef _DOUBLE_IS_32BITS
682  word1 (a) = 0;
683 #endif
684  }
685  else
686  {
687  word0 (a) = 0;
688  L -= Exp_shift;
689 #ifndef _DOUBLE_IS_32BITS
690  word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
691 #endif
692  }
693  }
694 #endif
695  return a.d;
696 }
697 
698 double
699 _DEFUN (b2d, (a, e),
700  _Bigint * a _AND int *e)
701 {
702  __ULong *xa, *xa0, w, y, z;
703  int k;
704  union double_union d;
705 #ifdef VAX
706  __ULong d0, d1;
707 #else
708 #define d0 word0(d)
709 #define d1 word1(d)
710 #endif
711 
712  xa0 = a->_x;
713  xa = xa0 + a->_wds;
714  y = *--xa;
715 #ifdef DEBUG
716  if (!y)
717  Bug ("zero y in b2d");
718 #endif
719  k = hi0bits (y);
720  *e = 32 - k;
721 #ifdef Pack_32
722  if (k < Ebits)
723  {
724  d0 = Exp_1 | y >> (Ebits - k);
725  w = xa > xa0 ? *--xa : 0;
726 #ifndef _DOUBLE_IS_32BITS
727  d1 = y << ((32 - Ebits) + k) | w >> (Ebits - k);
728 #endif
729  goto ret_d;
730  }
731  z = xa > xa0 ? *--xa : 0;
732  if (k -= Ebits)
733  {
734  d0 = Exp_1 | y << k | z >> (32 - k);
735  y = xa > xa0 ? *--xa : 0;
736 #ifndef _DOUBLE_IS_32BITS
737  d1 = z << k | y >> (32 - k);
738 #endif
739  }
740  else
741  {
742  d0 = Exp_1 | y;
743 #ifndef _DOUBLE_IS_32BITS
744  d1 = z;
745 #endif
746  }
747 #else
748  if (k < Ebits + 16)
749  {
750  z = xa > xa0 ? *--xa : 0;
751  d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
752  w = xa > xa0 ? *--xa : 0;
753  y = xa > xa0 ? *--xa : 0;
754  d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
755  goto ret_d;
756  }
757  z = xa > xa0 ? *--xa : 0;
758  w = xa > xa0 ? *--xa : 0;
759  k -= Ebits + 16;
760  d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
761  y = xa > xa0 ? *--xa : 0;
762  d1 = w << k + 16 | y << k;
763 #endif
764 ret_d:
765 #ifdef VAX
766  word0 (d) = d0 >> 16 | d0 << 16;
767  word1 (d) = d1 >> 16 | d1 << 16;
768 #else
769 #undef d0
770 #undef d1
771 #endif
772  return d.d;
773 }
774 
775 _Bigint *
776 _DEFUN (d2b,
777  (ptr, _d, e, bits),
778  struct _reent * ptr _AND
779  double _d _AND
780  int *e _AND
781  int *bits)
782 
783 {
784  union double_union d;
785  _Bigint *b;
786  int de, i, k;
787  __ULong *x, y, z;
788 #ifdef VAX
789  __ULong d0, d1;
790 #endif
791  d.d = _d;
792 #ifdef VAX
793  d0 = word0 (d) >> 16 | word0 (d) << 16;
794  d1 = word1 (d) >> 16 | word1 (d) << 16;
795 #else
796 #define d0 word0(d)
797 #define d1 word1(d)
798  d.d = _d;
799 #endif
800 
801 #ifdef Pack_32
802  b = Balloc (ptr, 1);
803 #else
804  b = Balloc (ptr, 2);
805 #endif
806  x = b->_x;
807 
808  z = d0 & Frac_mask;
809  d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
810 #ifdef Sudden_Underflow
811  de = (int) (d0 >> Exp_shift);
812 #ifndef IBM
813  z |= Exp_msk11;
814 #endif
815 #else
816  if ((de = (int) (d0 >> Exp_shift)) != 0)
817  z |= Exp_msk1;
818 #endif
819 #ifdef Pack_32
820 #ifndef _DOUBLE_IS_32BITS
821  if (d1)
822  {
823  y = d1;
824  k = lo0bits (&y);
825  if (k)
826  {
827  x[0] = y | z << (32 - k);
828  z >>= k;
829  }
830  else
831  x[0] = y;
832  i = b->_wds = (x[1] = z) ? 2 : 1;
833  }
834  else
835 #endif
836  {
837 #ifdef DEBUG
838  if (!z)
839  Bug ("Zero passed to d2b");
840 #endif
841  k = lo0bits (&z);
842  x[0] = z;
843  i = b->_wds = 1;
844 #ifndef _DOUBLE_IS_32BITS
845  k += 32;
846 #endif
847  }
848 #else
849  if (d1)
850  {
851  y = d1;
852  k = lo0bits (&y);
853  if (k)
854  if (k >= 16)
855  {
856  x[0] = y | z << 32 - k & 0xffff;
857  x[1] = z >> k - 16 & 0xffff;
858  x[2] = z >> k;
859  i = 2;
860  }
861  else
862  {
863  x[0] = y & 0xffff;
864  x[1] = y >> 16 | z << 16 - k & 0xffff;
865  x[2] = z >> k & 0xffff;
866  x[3] = z >> k + 16;
867  i = 3;
868  }
869  else
870  {
871  x[0] = y & 0xffff;
872  x[1] = y >> 16;
873  x[2] = z & 0xffff;
874  x[3] = z >> 16;
875  i = 3;
876  }
877  }
878  else
879  {
880 #ifdef DEBUG
881  if (!z)
882  Bug ("Zero passed to d2b");
883 #endif
884  k = lo0bits (&z);
885  if (k >= 16)
886  {
887  x[0] = z;
888  i = 0;
889  }
890  else
891  {
892  x[0] = z & 0xffff;
893  x[1] = z >> 16;
894  i = 1;
895  }
896  k += 32;
897  }
898  while (!x[i])
899  --i;
900  b->_wds = i + 1;
901 #endif
902 #ifndef Sudden_Underflow
903  if (de)
904  {
905 #endif
906 #ifdef IBM
907  *e = (de - Bias - (P - 1) << 2) + k;
908  *bits = 4 * P + 8 - k - hi0bits (word0 (d) & Frac_mask);
909 #else
910  *e = de - Bias - (P - 1) + k;
911  *bits = P - k;
912 #endif
913 #ifndef Sudden_Underflow
914  }
915  else
916  {
917  *e = de - Bias - (P - 1) + 1 + k;
918 #ifdef Pack_32
919  *bits = 32 * i - hi0bits (x[i - 1]);
920 #else
921  *bits = (i + 2) * 16 - hi0bits (x[i]);
922 #endif
923  }
924 #endif
925  return b;
926 }
927 #undef d0
928 #undef d1
929 
930 double
931 _DEFUN (ratio, (a, b), _Bigint * a _AND _Bigint * b)
932 
933 {
934  union double_union da, db;
935  int k, ka, kb;
936 
937  da.d = b2d (a, &ka);
938  db.d = b2d (b, &kb);
939 #ifdef Pack_32
940  k = ka - kb + 32 * (a->_wds - b->_wds);
941 #else
942  k = ka - kb + 16 * (a->_wds - b->_wds);
943 #endif
944 #ifdef IBM
945  if (k > 0)
946  {
947  word0 (da) += (k >> 2) * Exp_msk1;
948  if (k &= 3)
949  da.d *= 1 << k;
950  }
951  else
952  {
953  k = -k;
954  word0 (db) += (k >> 2) * Exp_msk1;
955  if (k &= 3)
956  db.d *= 1 << k;
957  }
958 #else
959  if (k > 0)
960  word0 (da) += k * Exp_msk1;
961  else
962  {
963  k = -k;
964  word0 (db) += k * Exp_msk1;
965  }
966 #endif
967  return da.d / db.d;
968 }
969 
970 
971 _CONST double
972  tens[] =
973 {
974  1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
975  1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
976  1e20, 1e21, 1e22, 1e23, 1e24
977 
978 };
979 
980 #if !defined(_DOUBLE_IS_32BITS) && !defined(__v800)
981 _CONST double bigtens[] =
982 {1e16, 1e32, 1e64, 1e128, 1e256};
983 
984 _CONST double tinytens[] =
985 {1e-16, 1e-32, 1e-64, 1e-128, 1e-256};
986 #else
987 _CONST double bigtens[] =
988 {1e16, 1e32};
989 
990 _CONST double tinytens[] =
991 {1e-16, 1e-32};
992 #endif
993 
994 
995 double
996 _DEFUN (_mprec_log10, (dig),
997  int dig)
998 {
999  double v = 1.0;
1000  if (dig < 24)
1001  return tens[dig];
1002  while (dig > 0)
1003  {
1004  v *= 10;
1005  dig--;
1006  }
1007  return v;
1008 }
1009 
1010 #endif // SMALL_LIB
1011 
1012 
1013 /*****************************************************************************************/
1014 /* FOR SMALL_LIB */
1015 /*****************************************************************************************/
1016 
1017 
1018 #ifdef SMALL_LIB
1019 
1020  /*
1021  * For SMALL_LIB, all references to balloc or bfree have been taken off
1022  * so as to avoided call of malloc libraries
1023  * For each function returning a _Bigint * we added to the function a parameter
1024  * of array type. The purpose of this array is to iniatialized pointers of _Bigint
1025  * with the address of the array instead of the adress provided by balloc.
1026  *
1027  */
1028 
1029 
1030 
1031 _Bigint *
1032 _DEFUN (small_multadd, (ptr, b, m, a, tab),
1033  struct _reent *ptr _AND
1034  _Bigint * b _AND
1035  int m _AND
1036  int a _AND
1037  _Bigint tab[])
1038 {
1039  int i, wds;
1040  __ULong *x, y;
1041 #ifdef Pack_32
1042  __ULong xi, z;
1043 #endif
1044  _Bigint *b1;
1045 
1046  wds = b->_wds;
1047  x = b->_x;
1048  i = 0;
1049  do
1050  {
1051 #ifdef Pack_32
1052  xi = *x;
1053  y = (xi & 0xffff) * m + a;
1054  z = (xi >> 16) * m + (y >> 16);
1055  a = (int) (z >> 16);
1056  *x++ = (z << 16) + (y & 0xffff);
1057 #else
1058  y = *x * m + a;
1059  a = (int) (y >> 16);
1060  *x++ = y & 0xffff;
1061 #endif
1062  }
1063  while (++i < wds);
1064  if (a)
1065  {
1066  if (wds >= b->_maxwds)
1067  {
1068  b1=&tab[0];
1069  b1->_k=b->_k+1;
1070  b1->_maxwds = (1 <<(b->_k+1));
1071  b1->_sign=b1->_wds=0;
1072  Bcopy(b1,b);
1073  b=b1;
1074  }
1075  b->_x[wds++] = a;
1076  b->_wds = wds;
1077  }
1078  return b;
1079 }
1080 
1081 
1082 _Bigint *
1083 _DEFUN (small_s2b, (ptr, s, nd0, nd, y9,tab),
1084  struct _reent * ptr _AND
1085  _CONST char *s _AND
1086  int nd0 _AND
1087  int nd _AND
1088  __ULong y9 _AND
1089  _Bigint tab[])
1090 {
1091  _Bigint *b;
1092  _Bigint tab_b[50];
1093  int i, k;
1094  __Long x, y;
1095 
1096  x = (nd + 8) / 9;
1097  for (k = 0, y = 1; x > y; y <<= 1, k++);
1098 #ifdef Pack_32
1099  b = &tab[0];
1100  b->_k=k;
1101  b->_maxwds = 1 <<k;
1102  b->_sign=0;
1103  b->_x[0] = y9;
1104  b->_wds = 1;
1105 #else
1106  b = &tab[0];
1107  b = &tab[0];
1108  b->_k=k+1;
1109  b->_mawxds = 1 <<(k+1);
1110  b->_sign=0;
1111  b->_x[0] = y9 & 0xffff;
1112  b->_wds = (b->_x[1] = y9 >> 16) ? 2 : 1;
1113 #endif
1114 
1115  i = 9;
1116  if (9 < nd0)
1117  {
1118  s += 9;
1119 
1120  while (++i < nd0);
1121  s++;
1122  }
1123  else
1124  s += 10;
1125  for (; i < nd; i++)
1126  b = small_multadd (ptr, b, 10, *s++ - '0',tab);
1127  return b;
1128 }
1129 
1130 int
1131 _DEFUN (small_hi0bits,
1132  (x), register __ULong x)
1133 {
1134  register int k = 0;
1135 
1136  if (!(x & 0xffff0000))
1137  {
1138  k = 16;
1139  x <<= 16;
1140  }
1141  if (!(x & 0xff000000))
1142  {
1143  k += 8;
1144  x <<= 8;
1145  }
1146  if (!(x & 0xf0000000))
1147  {
1148  k += 4;
1149  x <<= 4;
1150  }
1151  if (!(x & 0xc0000000))
1152  {
1153  k += 2;
1154  x <<= 2;
1155  }
1156  if (!(x & 0x80000000))
1157  {
1158  k++;
1159  if (!(x & 0x40000000))
1160  return 32;
1161  }
1162  return k;
1163 }
1164 
1165 int
1166 _DEFUN (small_lo0bits, (y), __ULong *y)
1167 {
1168  register int k;
1169  register __ULong x = *y;
1170 
1171  if (x & 7)
1172  {
1173  if (x & 1)
1174  return 0;
1175  if (x & 2)
1176  {
1177  *y = x >> 1;
1178  return 1;
1179  }
1180  *y = x >> 2;
1181  return 2;
1182  }
1183  k = 0;
1184  if (!(x & 0xffff))
1185  {
1186  k = 16;
1187  x >>= 16;
1188  }
1189  if (!(x & 0xff))
1190  {
1191  k += 8;
1192  x >>= 8;
1193  }
1194  if (!(x & 0xf))
1195  {
1196  k += 4;
1197  x >>= 4;
1198  }
1199  if (!(x & 0x3))
1200  {
1201  k += 2;
1202  x >>= 2;
1203  }
1204  if (!(x & 1))
1205  {
1206  k++;
1207  x >>= 1;
1208  if (!x & 1)
1209  return 32;
1210  }
1211  *y = x;
1212  return k;
1213 }
1214 
1215 
1216 _Bigint *
1217 _DEFUN (small_i2b, (ptr, i,tab), struct _reent * ptr _AND int i _AND _Bigint tab[])
1218 {
1219  _Bigint *b;
1220 
1221  b=&tab[0];
1222  b->_k=1;
1223  b->_maxwds = 1 << 1;
1224  b->_sign =0;
1225  b->_x[0] = i;
1226  b->_wds = 1;
1227  return b;
1228 }
1229 
1230 
1231 
1232 _Bigint *
1233 _DEFUN (small_mult, (ptr, a, b,tab), struct _reent * ptr _AND _Bigint * a _AND _Bigint * b _AND _Bigint tab[])
1234 {
1235  _Bigint *c;
1236  int k, wa, wb, wc;
1237  __ULong carry, y, z;
1238  __ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
1239 #ifdef Pack_32
1240  __ULong z2;
1241 #endif
1242 
1243  if (a->_wds < b->_wds)
1244  {
1245  c = a;
1246  a = b;
1247  b = c;
1248  }
1249  k = a->_k;
1250  wa = a->_wds;
1251  wb = b->_wds;
1252  wc = wa + wb;
1253  if (wc > a->_maxwds)
1254  k++;
1255  c=&tab[0];
1256  c->_k=k;
1257  c->_maxwds = 1 << k;
1258  c->_sign= c->_wds =0;
1259 
1260  for (x = c->_x, xa = x + wc; x < xa; x++)
1261  *x = 0;
1262  xa = a->_x;
1263  xae = xa + wa;
1264  xb = b->_x;
1265  xbe = xb + wb;
1266  xc0 = c->_x;
1267 #ifdef Pack_32
1268  for (; xb < xbe; xb++, xc0++)
1269  {
1270  if ((y = *xb & 0xffff) != 0)
1271  {
1272  x = xa;
1273  xc = xc0;
1274  carry = 0;
1275  do
1276  {
1277  z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
1278  carry = z >> 16;
1279  z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
1280  carry = z2 >> 16;
1281  Storeinc (xc, z2, z);
1282  }
1283  while (x < xae);
1284  *xc = carry;
1285  }
1286  if ((y = *xb >> 16) != 0)
1287  {
1288  x = xa;
1289  xc = xc0;
1290  carry = 0;
1291  z2 = *xc;
1292  do
1293  {
1294  z = (*x & 0xffff) * y + (*xc >> 16) + carry;
1295  carry = z >> 16;
1296  Storeinc (xc, z, z2);
1297  z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
1298  carry = z2 >> 16;
1299  }
1300  while (x < xae);
1301  *xc = z2;
1302  }
1303  }
1304 #else
1305  for (; xb < xbe; xc0++)
1306  {
1307  if (y = *xb++)
1308  {
1309  x = xa;
1310  xc = xc0;
1311  carry = 0;
1312  do
1313  {
1314  z = *x++ * y + *xc + carry;
1315  carry = z >> 16;
1316  *xc++ = z & 0xffff;
1317  }
1318  while (x < xae);
1319  *xc = carry;
1320  }
1321  }
1322 #endif
1323  for (xc0 = c->_x, xc = xc0 + wc; wc > 0 && !*--xc; --wc);
1324  c->_wds = wc;
1325  return c;
1326 }
1327 
1328 
1329 
1330 _Bigint *
1331 _DEFUN (small_pow5mult,
1332  (ptr, b, k, tab), struct _reent * ptr _AND _Bigint * b _AND int k _AND _Bigint tab[])
1333 {
1334  _Bigint *b1, *p5, *p51;
1335  _Bigint tab_p5[50], tab_p5mult[50];
1336  _Bigint tab_b2[40], tab_b1[40];
1337  int i;
1338  int k_sauv;
1339  static _CONST int p05[3] = {5, 25, 125};
1340  if ((i = k & 3) != 0){
1341  k_sauv=k;
1342  k_sauv >>= 2;
1343  if (!(k_sauv)){ // we anticipate the case !(k>>=2) with return so as
1344  //to provide the good address &tab[0]
1345  b = small_multadd (ptr, b, p05[i - 1], 0,&tab[0]);
1346  return b;
1347  }
1348  else{
1349  b = small_multadd (ptr, b, p05[i - 1], 0,&tab_b1[0]); //&tab_b1[0] is an temporary address that
1350  // that we provide to b
1351  }
1352  }
1353  if (!(k>>= 2)){
1354  return b;
1355  }
1356  if (p5 != tab_p5 ){ /* first time */
1357  p5 =small_i2b (ptr, 625,tab_p5);
1358  p5->_next = 0;
1359  }
1360 
1361  for (;;) {// We are in a loop for each variable and call of mult we must provide a
1362  // an address which differs from the current address of the variable
1363  // that is why we add a test on the current address
1364 
1365  if (k & 1){
1366 
1367  k_sauv = k ;
1368  if (!(k_sauv >>= 1) ){ // it is the last passage in the loop
1369  // we must provide the good address
1370  b1 = small_mult (ptr, b, p5,&tab[0]);
1371  b = b1;
1372  break;
1373  }
1374  else {
1375  if (b == &tab_b1[0]){
1376  b1 = small_mult (ptr, b, p5,&tab_b2[0]);
1377  }
1378  else {
1379  b1 = small_mult (ptr, b, p5,&tab_b1[0]);
1380  }
1381  }
1382  b = b1;
1383  }
1384  if (!(k >>= 1))
1385  break;
1386  if (!(p51 = p5->_next))
1387  {
1388  if ( p5 == &tab_p5[0] ){
1389  p51 = p5->_next = small_mult (ptr, p5, p5,&tab_p5mult[0]);
1390  }
1391  else {
1392  p51 = p5->_next = small_mult (ptr, p5, p5,&tab_p5[0]);
1393  }
1394  p51->_next = 0;
1395  }
1396  p5 = p51;
1397  }
1398  return b;
1399 }
1400 
1401 
1402 _Bigint *
1403 _DEFUN (small_lshift, (ptr, b, k,tab), struct _reent * ptr _AND _Bigint * b _AND int k _AND _Bigint tab[] )
1404 {
1405  int i, k1, n, n1;
1406  _Bigint *b1;
1407  __ULong *x, *x1, *xe, z;
1408 
1409 #ifdef Pack_32
1410  n = k >> 5;
1411 #else
1412  n = k >> 4;
1413 #endif
1414  k1 = b->_k;
1415  n1 = n + b->_wds + 1;
1416  for (i = b->_maxwds; n1 > i; i <<= 1)
1417  k1++;
1418  //b1 = Balloc (ptr, k1);
1419  b1=&tab[0];
1420  b1->_k=k1;
1421  b1->_maxwds = 1 << k1;
1422  b1->_sign= b1->_wds =0;
1423  x1 = b1->_x;
1424  for (i = 0; i < n; i++)
1425  *x1++ = 0;
1426  x = b->_x;
1427  xe = x + b->_wds;
1428 #ifdef Pack_32
1429  if (k &= 0x1f)
1430  {
1431  k1 = 32 - k;
1432  z = 0;
1433  do
1434  {
1435  *x1++ = *x << k | z;
1436  z = *x++ >> k1;
1437  }
1438  while (x < xe);
1439  if ((*x1 = z) != 0)
1440  ++n1;
1441  }
1442 #else
1443  if (k &= 0xf)
1444  {
1445  k1 = 16 - k;
1446  z = 0;
1447  do
1448  {
1449  *x1++ = *x << k & 0xffff | z;
1450  z = *x++ >> k1;
1451  }
1452  while (x < xe);
1453  if (*x1 = z)
1454  ++n1;
1455  }
1456 #endif
1457  else
1458  do
1459  *x1++ = *x++;
1460  while (x < xe);
1461  b1->_wds = n1 - 1;
1462  //Bfree (ptr, b);
1463  return b1;
1464 }
1465 
1466 int
1467 _DEFUN (small_cmp, (a, b), _Bigint * a _AND _Bigint * b)
1468 {
1469  __ULong *xa, *xa0, *xb, *xb0;
1470  int i, j;
1471 
1472  i = a->_wds;
1473  j = b->_wds;
1474 #ifdef DEBUG
1475  if (i > 1 && !a->_x[i - 1])
1476  Bug ("cmp called with a->_x[a->_wds-1] == 0");
1477  if (j > 1 && !b->_x[j - 1])
1478  Bug ("cmp called with b->_x[b->_wds-1] == 0");
1479 #endif
1480  if (i -= j)
1481  return i;
1482  xa0 = a->_x;
1483  xa = xa0 + j;
1484  xb0 = b->_x;
1485  xb = xb0 + j;
1486  for (;;)
1487  {
1488  if (*--xa != *--xb)
1489  return *xa < *xb ? -1 : 1;
1490  if (xa <= xa0)
1491  break;
1492  }
1493  return 0;
1494 }
1495 
1496 
1497 
1498 _Bigint *
1499 _DEFUN (small_diff, (ptr, a, b,tab), struct _reent * ptr _AND
1500  _Bigint * a _AND _Bigint * b _AND _Bigint tab[])
1501 {
1502  _Bigint *c;
1503  int i, wa, wb;
1504  __Long borrow, y; /* We need signed shifts here. */
1505  __ULong *xa, *xae, *xb, *xbe, *xc;
1506 #ifdef Pack_32
1507  __Long z;
1508 #endif
1509 
1510  i = small_cmp (a, b);
1511  if (!i)
1512  {
1513  c=&tab[0];
1514  c->_k = 0;
1515  c->_maxwds = (1 << 0) ;
1516  c->_sign = 0 ;
1517  c->_wds = 1;
1518  c->_x[0] = 0;
1519  return c;
1520  }
1521  if (i < 0)
1522  {
1523  c = a;
1524  a = b;
1525  b = c;
1526  i = 1;
1527  }
1528  else
1529  i = 0;
1530  c=&tab[0];
1531  c->_k = a->_k;
1532  c->_maxwds = (1 << (a->_k)) ;
1533  c->_wds = 0 ;
1534  c->_sign = i;
1535  wa = a->_wds;
1536  xa = a->_x;
1537  xae = xa + wa;
1538  wb = b->_wds;
1539  xb = b->_x;
1540  xbe = xb + wb;
1541  xc = c->_x;
1542  borrow = 0;
1543 #ifdef Pack_32
1544  do
1545  {
1546  y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
1547  borrow = y >> 16;
1548  Sign_Extend (borrow, y);
1549  z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
1550  borrow = z >> 16;
1551  Sign_Extend (borrow, z);
1552  Storeinc (xc, z, y);
1553  }
1554  while (xb < xbe);
1555  while (xa < xae)
1556  {
1557  y = (*xa & 0xffff) + borrow;
1558  borrow = y >> 16;
1559  Sign_Extend (borrow, y);
1560  z = (*xa++ >> 16) + borrow;
1561  borrow = z >> 16;
1562  Sign_Extend (borrow, z);
1563  Storeinc (xc, z, y);
1564  }
1565 #else
1566  do
1567  {
1568  y = *xa++ - *xb++ + borrow;
1569  borrow = y >> 16;
1570  Sign_Extend (borrow, y);
1571  *xc++ = y & 0xffff;
1572  }
1573  while (xb < xbe);
1574  while (xa < xae)
1575  {
1576  y = *xa++ + borrow;
1577  borrow = y >> 16;
1578  Sign_Extend (borrow, y);
1579  *xc++ = y & 0xffff;
1580  }
1581 #endif
1582  while (!*--xc)
1583  wa--;
1584  c->_wds = wa;
1585  return c;
1586 }
1587 
1588 double
1589 _DEFUN (small_ulp, (_x), double _x)
1590 {
1591  union double_union x, a;
1592  register __Long L;
1593 
1594  x.d = _x;
1595 
1596  L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
1597 #ifndef Sudden_Underflow
1598  if (L > 0)
1599  {
1600 #endif
1601 #ifdef IBM
1602  L |= Exp_msk1 >> 4;
1603 #endif
1604  word0 (a) = L;
1605 #ifndef _DOUBLE_IS_32BITS
1606  word1 (a) = 0;
1607 #endif
1608 
1609 #ifndef Sudden_Underflow
1610  }
1611  else
1612  {
1613  L = -L >> Exp_shift;
1614  if (L < Exp_shift)
1615  {
1616  word0 (a) = 0x80000 >> L;
1617 #ifndef _DOUBLE_IS_32BITS
1618  word1 (a) = 0;
1619 #endif
1620  }
1621  else
1622  {
1623  word0 (a) = 0;
1624  L -= Exp_shift;
1625 #ifndef _DOUBLE_IS_32BITS
1626  word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
1627 #endif
1628  }
1629  }
1630 #endif
1631  return a.d;
1632 }
1633 
1634 double
1635 _DEFUN (small_b2d, (a, e),
1636  _Bigint * a _AND int *e)
1637 {
1638  __ULong *xa, *xa0, w, y, z;
1639  int k;
1640  union double_union d;
1641 #ifdef VAX
1642  __ULong d0, d1;
1643 #else
1644 #define d0 word0(d)
1645 #define d1 word1(d)
1646 #endif
1647 
1648  xa0 = a->_x;
1649  xa = xa0 + a->_wds;
1650  y = *--xa;
1651 #ifdef DEBUG
1652  if (!y)
1653  Bug ("zero y in b2d");
1654 #endif
1655  k = small_hi0bits (y);
1656  *e = 32 - k;
1657 #ifdef Pack_32
1658  if (k < Ebits)
1659  {
1660  d0 = Exp_1 | y >> (Ebits - k);
1661  w = xa > xa0 ? *--xa : 0;
1662 #ifndef _DOUBLE_IS_32BITS
1663  d1 = y << ((32 - Ebits) + k) | w >> (Ebits - k);
1664 #endif
1665  goto ret_d;
1666  }
1667  z = xa > xa0 ? *--xa : 0;
1668  if (k -= Ebits)
1669  {
1670  d0 = Exp_1 | y << k | z >> (32 - k);
1671  y = xa > xa0 ? *--xa : 0;
1672 #ifndef _DOUBLE_IS_32BITS
1673  d1 = z << k | y >> (32 - k);
1674 #endif
1675  }
1676  else
1677  {
1678  d0 = Exp_1 | y;
1679 #ifndef _DOUBLE_IS_32BITS
1680  d1 = z;
1681 #endif
1682  }
1683 #else
1684  if (k < Ebits + 16)
1685  {
1686  z = xa > xa0 ? *--xa : 0;
1687  d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
1688  w = xa > xa0 ? *--xa : 0;
1689  y = xa > xa0 ? *--xa : 0;
1690  d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
1691  goto ret_d;
1692  }
1693  z = xa > xa0 ? *--xa : 0;
1694  w = xa > xa0 ? *--xa : 0;
1695  k -= Ebits + 16;
1696  d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
1697  y = xa > xa0 ? *--xa : 0;
1698  d1 = w << k + 16 | y << k;
1699 #endif
1700 ret_d:
1701 #ifdef VAX
1702  word0 (d) = d0 >> 16 | d0 << 16;
1703  word1 (d) = d1 >> 16 | d1 << 16;
1704 #else
1705 #undef d0
1706 #undef d1
1707 #endif
1708  return d.d;
1709 }
1710 
1711 
1712 _Bigint *
1713 _DEFUN (small_d2b,
1714  (ptr, _d, e, bits,tab),
1715  struct _reent * ptr _AND
1716  double _d _AND
1717  int *e _AND
1718  int *bits _AND
1719  _Bigint tab[]
1720  )
1721 
1722 {
1723  union double_union d;
1724  _Bigint *b;
1725 
1726  int de, i, k;
1727  __ULong *x, y, z;
1728 #ifdef VAX
1729  __ULong d0, d1;
1730 #endif
1731  d.d = _d;
1732 #ifdef VAX
1733  d0 = word0 (d) >> 16 | word0 (d) << 16;
1734  d1 = word1 (d) >> 16 | word1 (d) << 16;
1735 #else
1736 #define d0 word0(d)
1737 #define d1 word1(d)
1738  d.d = _d;
1739 #endif
1740 
1741 #ifdef Pack_32
1742  b=&tab[0];
1743  b->_k = 1;
1744  b->_maxwds = (1 << 1) ;
1745  b->_sign = b->_wds = 0 ;
1746 
1747 #else
1748  b=&tab[0];
1749  b->_k = 2;
1750  b->_maxwds = (1 << 2) ;
1751  b->_sign = b->_wds = 0 ;
1752 #endif
1753 
1754 
1755  x = b->_x;
1756 
1757  z = d0 & Frac_mask;
1758  d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
1759 #ifdef Sudden_Underflow
1760  de = (int) (d0 >> Exp_shift);
1761 #ifndef IBM
1762  z |= Exp_msk11;
1763 #endif
1764 #else
1765  if ((de = (int) (d0 >> Exp_shift)) != 0)
1766  z |= Exp_msk1;
1767 #endif
1768 #ifdef Pack_32
1769 #ifndef _DOUBLE_IS_32BITS
1770  if (d1)
1771  {
1772  y = d1;
1773  k = small_lo0bits (&y);
1774  if (k)
1775  {
1776  x[0] = y | z << (32 - k);
1777  z >>= k;
1778  }
1779  else
1780  x[0] = y;
1781  i = b->_wds = (x[1] = z) ? 2 : 1;
1782  }
1783  else
1784 #endif
1785  {
1786 #ifdef DEBUG
1787  if (!z)
1788  Bug ("Zero passed to d2b");
1789 #endif
1790  k = small_lo0bits (&z);
1791  x[0] = z;
1792  i = b->_wds = 1;
1793 #ifndef _DOUBLE_IS_32BITS
1794  k += 32;
1795 #endif
1796  }
1797 #else
1798  if (d1)
1799  {
1800  y = d1;
1801  k = small_lo0bits (&y);
1802  if (k)
1803  if (k >= 16)
1804  {
1805  x[0] = y | z << 32 - k & 0xffff;
1806  x[1] = z >> k - 16 & 0xffff;
1807  x[2] = z >> k;
1808  i = 2;
1809  }
1810  else
1811  {
1812  x[0] = y & 0xffff;
1813  x[1] = y >> 16 | z << 16 - k & 0xffff;
1814  x[2] = z >> k & 0xffff;
1815  x[3] = z >> k + 16;
1816  i = 3;
1817  }
1818  else
1819  {
1820  x[0] = y & 0xffff;
1821  x[1] = y >> 16;
1822  x[2] = z & 0xffff;
1823  x[3] = z >> 16;
1824  i = 3;
1825  }
1826  }
1827  else
1828  {
1829 #ifdef DEBUG
1830  if (!z)
1831  Bug ("Zero passed to d2b");
1832 #endif
1833  k = lo0bits (&z);
1834  if (k >= 16)
1835  {
1836  x[0] = z;
1837  i = 0;
1838  }
1839  else
1840  {
1841  x[0] = z & 0xffff;
1842  x[1] = z >> 16;
1843  i = 1;
1844  }
1845  k += 32;
1846  }
1847  while (!x[i])
1848  --i;
1849  b->_wds = i + 1;
1850 #endif
1851 #ifndef Sudden_Underflow
1852  if (de)
1853  {
1854 #endif
1855 #ifdef IBM
1856  *e = (de - Bias - (P - 1) << 2) + k;
1857  *bits = 4 * P + 8 - k - small_hi0bits (word0 (d) & Frac_mask);
1858 #else
1859  *e = de - Bias - (P - 1) + k;
1860  *bits = P - k;
1861 #endif
1862 #ifndef Sudden_Underflow
1863  }
1864  else
1865  {
1866  *e = de - Bias - (P - 1) + 1 + k;
1867 #ifdef Pack_32
1868  *bits = 32 * i - small_hi0bits (x[i - 1]);
1869 #else
1870  *bits = (i + 2) * 16 - small_hi0bits (x[i]);
1871 #endif
1872  }
1873 #endif
1874  return b;
1875 }
1876 #undef d0
1877 #undef d1
1878 
1879 double
1880 _DEFUN (small_ratio, (a, b), _Bigint * a _AND _Bigint * b)
1881 
1882 {
1883  union double_union da, db;
1884  int k, ka, kb;
1885 
1886  da.d = small_b2d (a, &ka);
1887  db.d = small_b2d (b, &kb);
1888 #ifdef Pack_32
1889  k = ka - kb + 32 * (a->_wds - b->_wds);
1890 #else
1891  k = ka - kb + 16 * (a->_wds - b->_wds);
1892 #endif
1893 #ifdef IBM
1894  if (k > 0)
1895  {
1896  word0 (da) += (k >> 2) * Exp_msk1;
1897  if (k &= 3)
1898  da.d *= 1 << k;
1899  }
1900  else
1901  {
1902  k = -k;
1903  word0 (db) += (k >> 2) * Exp_msk1;
1904  if (k &= 3)
1905  db.d *= 1 << k;
1906  }
1907 #else
1908  if (k > 0)
1909  word0 (da) += k * Exp_msk1;
1910  else
1911  {
1912  k = -k;
1913  word0 (db) += k * Exp_msk1;
1914  }
1915 #endif
1916  return da.d / db.d;
1917 }
1918 
1919 
1920 _CONST double
1921  small_tens[] =
1922 {
1923  1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1924  1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1925  1e20, 1e21, 1e22, 1e23, 1e24
1926 
1927 };
1928 
1929 #if !defined(_DOUBLE_IS_32BITS) && !defined(__v800)
1930 _CONST double small_bigtens[] =
1931 {1e16, 1e32, 1e64, 1e128, 1e256};
1932 
1933 _CONST double small_tinytens[] =
1934 {1e-16, 1e-32, 1e-64, 1e-128, 1e-256};
1935 #else
1936 _CONST double small_bigtens[] =
1937 {1e16, 1e32};
1938 
1939 _CONST double small_tinytens[] =
1940 {1e-16, 1e-32};
1941 #endif
1942 
1943 
1944 
1945 
1946 double
1947 _DEFUN (small__mprec_log10, (dig),
1948  int dig)
1949 {
1950  double v = 1.0;
1951  if (dig < 24)
1952  return small_tens[dig];
1953  while (dig > 0)
1954  {
1955  v *= 10;
1956  dig--;
1957  }
1958  return v;
1959 }
1960 
1961 #endif // SMALL_PRINTF
1962 
1963