00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 #include "autoconf.h"
00132 #include "config.h"
00133 #include "externs.h"
00134 #include "stringutil.h"
00135
00136 #if defined(HAVE_FPU_CONTROL_H)
00137 #include <fpu_control.h>
00138 #elif defined(IEEEFP_H_USEABLE)
00139 #include <ieeefp.h>
00140 #elif defined(HAVE_FENV_H)
00141 #include <fenv.h>
00142 #endif
00143
00144 #if defined(WORDS_BIGENDIAN)
00145 #define IEEE_MC68k
00146 #elif defined(WORDS_LITTLEENDIAN)
00147 #define IEEE_8087
00148 #else
00149 #error Must be either Big or Little Endian.
00150 #endif
00151
00152 #define Long INT32
00153 typedef UINT32 ULong;
00154
00155 #ifndef Omit_Private_Memory
00156 #ifndef PRIVATE_MEM
00157 #define PRIVATE_MEM 2304
00158 #endif
00159 #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
00160 static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
00161 #endif
00162
00163 #undef IEEE_Arith
00164 #undef Avoid_Underflow
00165 #ifdef IEEE_MC68k
00166 #define IEEE_Arith
00167 #endif
00168 #ifdef IEEE_8087
00169 #define IEEE_Arith
00170 #endif
00171
00172 #ifdef Bad_float_h
00173
00174 #ifdef IEEE_Arith
00175 #define DBL_DIG 15
00176 #define DBL_MAX_10_EXP 308
00177 #define DBL_MAX_EXP 1024
00178 #define FLT_RADIX 2
00179 #endif
00180
00181 #ifdef IBM
00182 #define DBL_DIG 16
00183 #define DBL_MAX_10_EXP 75
00184 #define DBL_MAX_EXP 63
00185 #define FLT_RADIX 16
00186 #define DBL_MAX 7.2370055773322621e+75
00187 #endif
00188
00189 #ifdef VAX
00190 #define DBL_DIG 16
00191 #define DBL_MAX_10_EXP 38
00192 #define DBL_MAX_EXP 127
00193 #define FLT_RADIX 2
00194 #define DBL_MAX 1.7014118346046923e+38
00195 #endif
00196
00197 #ifndef LONG_MAX
00198 #define LONG_MAX 2147483647
00199 #endif
00200
00201 #else
00202 #include "float.h"
00203 #endif
00204
00205 #ifndef __MATH_H__
00206 #include "math.h"
00207 #endif
00208
00209 #ifndef CONST
00210 #define CONST const
00211 #endif
00212
00213 #if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
00214 Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
00215 #endif
00216
00217 typedef union
00218 {
00219 double d;
00220 ULong L[2];
00221 } U;
00222
00223 #ifdef YES_ALIAS
00224 #define dval(x) x
00225 #ifdef IEEE_8087
00226 #define word0(x) ((ULong *)&x)[1]
00227 #define word1(x) ((ULong *)&x)[0]
00228 #else
00229 #define word0(x) ((ULong *)&x)[0]
00230 #define word1(x) ((ULong *)&x)[1]
00231 #endif
00232 #else
00233 #ifdef IEEE_8087
00234 #define word0(x) ((U*)&x)->L[1]
00235 #define word1(x) ((U*)&x)->L[0]
00236 #else
00237 #define word0(x) ((U*)&x)->L[0]
00238 #define word1(x) ((U*)&x)->L[1]
00239 #endif
00240 #define dval(x) ((U*)&x)->d
00241 #endif
00242
00243
00244
00245
00246
00247 #if defined(IEEE_8087) + defined(VAX)
00248 #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
00249 ((unsigned short *)a)[0] = (unsigned short)c, a++)
00250 #else
00251 #define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
00252 ((unsigned short *)a)[1] = (unsigned short)c, a++)
00253 #endif
00254
00255
00256
00257
00258
00259
00260
00261 #ifdef IEEE_Arith
00262 #define Exp_shift 20
00263 #define Exp_shift1 20
00264 #define Exp_msk1 0x100000
00265 #define Exp_msk11 0x100000
00266 #define Exp_mask 0x7ff00000
00267 #define P 53
00268 #define Bias 1023
00269 #define Emin (-1022)
00270 #define Exp_1 0x3ff00000
00271 #define Exp_11 0x3ff00000
00272 #define Ebits 11
00273 #define Frac_mask 0xfffff
00274 #define Frac_mask1 0xfffff
00275 #define Ten_pmax 22
00276 #define Bletch 0x10
00277 #define Bndry_mask 0xfffff
00278 #define Bndry_mask1 0xfffff
00279 #define LSB 1
00280 #define Sign_bit 0x80000000
00281 #define Log2P 1
00282 #define Tiny0 0
00283 #define Tiny1 1
00284 #define Quick_max 14
00285 #define Int_max 14
00286 #ifndef NO_IEEE_Scale
00287 #define Avoid_Underflow
00288 #ifdef Flush_Denorm
00289 #undef Sudden_Underflow
00290 #endif
00291 #endif
00292
00293 #ifndef Flt_Rounds
00294 #ifdef FLT_ROUNDS
00295 #define Flt_Rounds FLT_ROUNDS
00296 #else
00297 #define Flt_Rounds 1
00298 #endif
00299 #endif
00300
00301 #ifdef Honor_FLT_ROUNDS
00302 #define Rounding rounding
00303 #undef Check_FLT_ROUNDS
00304 #define Check_FLT_ROUNDS
00305 #else
00306 #define Rounding Flt_Rounds
00307 #endif
00308
00309 #else
00310 #undef Check_FLT_ROUNDS
00311 #undef Honor_FLT_ROUNDS
00312 #undef SET_INEXACT
00313 #undef Sudden_Underflow
00314 #define Sudden_Underflow
00315 #ifdef IBM
00316 #undef Flt_Rounds
00317 #define Flt_Rounds 0
00318 #define Exp_shift 24
00319 #define Exp_shift1 24
00320 #define Exp_msk1 0x1000000
00321 #define Exp_msk11 0x1000000
00322 #define Exp_mask 0x7f000000
00323 #define P 14
00324 #define Bias 65
00325 #define Exp_1 0x41000000
00326 #define Exp_11 0x41000000
00327 #define Ebits 8
00328 #define Frac_mask 0xffffff
00329 #define Frac_mask1 0xffffff
00330 #define Bletch 4
00331 #define Ten_pmax 22
00332 #define Bndry_mask 0xefffff
00333 #define Bndry_mask1 0xffffff
00334 #define LSB 1
00335 #define Sign_bit 0x80000000
00336 #define Log2P 4
00337 #define Tiny0 0x100000
00338 #define Tiny1 0
00339 #define Quick_max 14
00340 #define Int_max 15
00341 #else
00342 #undef Flt_Rounds
00343 #define Flt_Rounds 1
00344 #define Exp_shift 23
00345 #define Exp_shift1 7
00346 #define Exp_msk1 0x80
00347 #define Exp_msk11 0x800000
00348 #define Exp_mask 0x7f80
00349 #define P 56
00350 #define Bias 129
00351 #define Exp_1 0x40800000
00352 #define Exp_11 0x4080
00353 #define Ebits 8
00354 #define Frac_mask 0x7fffff
00355 #define Frac_mask1 0xffff007f
00356 #define Ten_pmax 24
00357 #define Bletch 2
00358 #define Bndry_mask 0xffff007f
00359 #define Bndry_mask1 0xffff007f
00360 #define LSB 0x10000
00361 #define Sign_bit 0x8000
00362 #define Log2P 1
00363 #define Tiny0 0x80
00364 #define Tiny1 0
00365 #define Quick_max 15
00366 #define Int_max 15
00367 #endif
00368 #endif
00369
00370 #ifndef IEEE_Arith
00371 #define ROUND_BIASED
00372 #endif
00373
00374 #ifdef RND_PRODQUOT
00375 #define rounded_product(a,b) a = rnd_prod(a, b)
00376 #define rounded_quotient(a,b) a = rnd_quot(a, b)
00377 extern double rnd_prod(double, double), rnd_quot(double, double);
00378 #else
00379 #define rounded_product(a,b) a *= b
00380 #define rounded_quotient(a,b) a /= b
00381 #endif
00382
00383 #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
00384 #define Big1 0xffffffff
00385
00386 #ifndef Pack_32
00387 #define Pack_32
00388 #endif
00389
00390 #define FFFFFFFF 0xffffffffUL
00391
00392 #ifndef Llong
00393 #define Llong INT64
00394 #endif
00395 #ifndef ULLong
00396 #define ULLong UINT64
00397 #endif
00398
00399 #define Kmax 15
00400
00401 struct Bigint
00402 {
00403 struct Bigint *next;
00404 int k, maxwds, sign, wds;
00405 ULong x[1];
00406 };
00407
00408 typedef struct Bigint Bigint;
00409
00410 static Bigint *freelist[Kmax+1];
00411
00412 static Bigint *Balloc(int k)
00413 {
00414 int x;
00415 Bigint *rv;
00416 #ifndef Omit_Private_Memory
00417 unsigned int len;
00418 #endif
00419
00420 if ((rv = freelist[k]))
00421 {
00422 freelist[k] = rv->next;
00423 }
00424 else
00425 {
00426 x = 1 << k;
00427 #ifdef Omit_Private_Memory
00428 rv = (Bigint *)MEMALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong));
00429 ISOUTOFMEMORY(rv);
00430 #else
00431 len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
00432 /sizeof(double);
00433 if (pmem_next - private_mem + len <= PRIVATE_mem)
00434 {
00435 rv = (Bigint*)pmem_next;
00436 pmem_next += len;
00437 }
00438 else
00439 {
00440 rv = (Bigint*)MEMALLOC(len*sizeof(double));
00441 ISOUTOFMEMORY(rv);
00442 }
00443 #endif
00444 rv->k = k;
00445 rv->maxwds = x;
00446 }
00447 rv->sign = rv->wds = 0;
00448 return rv;
00449 }
00450
00451 static void Bfree(Bigint *v)
00452 {
00453 if (v)
00454 {
00455 v->next = freelist[v->k];
00456 freelist[v->k] = v;
00457 }
00458 }
00459
00460 #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
00461 y->wds*sizeof(Long) + 2*sizeof(int))
00462
00463
00464
00465 static Bigint *multadd(Bigint *b, int m, int a)
00466 {
00467 int i, wds;
00468 #ifdef ULLong
00469 ULong *x;
00470 ULLong carry, y;
00471 #else
00472 ULong carry, *x, y;
00473 #ifdef Pack_32
00474 ULong xi, z;
00475 #endif
00476 #endif
00477 Bigint *b1;
00478
00479 wds = b->wds;
00480 x = b->x;
00481 i = 0;
00482 carry = a;
00483 do
00484 {
00485 #ifdef ULLong
00486 y = *x * (ULLong)m + carry;
00487 carry = y >> 32;
00488 *x++ = (unsigned int)(y & 0xFFFFFFFF);
00489 #else
00490 #ifdef Pack_32
00491 xi = *x;
00492 y = (xi & 0xffff) * m + carry;
00493 z = (xi >> 16) * m + (y >> 16);
00494 carry = z >> 16;
00495 *x++ = (z << 16) + (y & 0xffff);
00496 #else
00497 y = *x * m + carry;
00498 carry = y >> 16;
00499 *x++ = y & 0xffff;
00500 #endif
00501 #endif
00502 } while (++i < wds);
00503 if (carry)
00504 {
00505 if (wds >= b->maxwds)
00506 {
00507 b1 = Balloc(b->k+1);
00508 Bcopy(b1, b);
00509 Bfree(b);
00510 b = b1;
00511 }
00512 b->x[wds++] = (unsigned int)carry;
00513 b->wds = wds;
00514 }
00515 return b;
00516 }
00517
00518 static Bigint *s2b(CONST char *s, int nd0, int nd, ULong y9)
00519 {
00520 Bigint *b;
00521 int i, k;
00522 Long x, y;
00523
00524 x = (nd + 8) / 9;
00525 for (k = 0, y = 1; x > y; y <<= 1, k++)
00526 {
00527 ;
00528 }
00529 #ifdef Pack_32
00530 b = Balloc(k);
00531 b->x[0] = y9;
00532 b->wds = 1;
00533 #else
00534 b = Balloc(k+1);
00535 b->x[0] = y9 & 0xffff;
00536 b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
00537 #endif
00538
00539 i = 9;
00540 if (9 < nd0)
00541 {
00542 s += 9;
00543 do
00544 {
00545 b = multadd(b, 10, *s++ - '0');
00546 } while (++i < nd0);
00547 s++;
00548 }
00549 else
00550 {
00551 s += 10;
00552 }
00553 for (; i < nd; i++)
00554 {
00555 b = multadd(b, 10, *s++ - '0');
00556 }
00557 return b;
00558 }
00559
00560 static int hi0bits(register ULong x)
00561 {
00562 register int k = 0;
00563
00564 if (!(x & 0xffff0000))
00565 {
00566 k = 16;
00567 x <<= 16;
00568 }
00569 if (!(x & 0xff000000))
00570 {
00571 k += 8;
00572 x <<= 8;
00573 }
00574 if (!(x & 0xf0000000))
00575 {
00576 k += 4;
00577 x <<= 4;
00578 }
00579 if (!(x & 0xc0000000))
00580 {
00581 k += 2;
00582 x <<= 2;
00583 }
00584 if (!(x & 0x80000000))
00585 {
00586 k++;
00587 if (!(x & 0x40000000))
00588 {
00589 return 32;
00590 }
00591 }
00592 return k;
00593 }
00594
00595 static int lo0bits(ULong *y)
00596 {
00597 register int k;
00598 register ULong x = *y;
00599
00600 if (x & 7)
00601 {
00602 if (x & 1)
00603 {
00604 return 0;
00605 }
00606 if (x & 2)
00607 {
00608 *y = x >> 1;
00609 return 1;
00610 }
00611 *y = x >> 2;
00612 return 2;
00613 }
00614 k = 0;
00615 if (!(x & 0xffff))
00616 {
00617 k = 16;
00618 x >>= 16;
00619 }
00620 if (!(x & 0xff))
00621 {
00622 k += 8;
00623 x >>= 8;
00624 }
00625 if (!(x & 0xf))
00626 {
00627 k += 4;
00628 x >>= 4;
00629 }
00630 if (!(x & 0x3))
00631 {
00632 k += 2;
00633 x >>= 2;
00634 }
00635 if (!(x & 1))
00636 {
00637 k++;
00638 x >>= 1;
00639 if (!(x & 1))
00640 {
00641 return 32;
00642 }
00643 }
00644 *y = x;
00645 return k;
00646 }
00647
00648 static Bigint *i2b(int i)
00649 {
00650 Bigint *b;
00651
00652 b = Balloc(1);
00653 b->x[0] = i;
00654 b->wds = 1;
00655 return b;
00656 }
00657
00658 static Bigint *mult(Bigint *a, Bigint *b)
00659 {
00660 Bigint *c;
00661 int k, wa, wb, wc;
00662 ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
00663 ULong y;
00664 #ifdef ULLong
00665 ULLong carry, z;
00666 #else
00667 ULong carry, z;
00668 #ifdef Pack_32
00669 ULong z2;
00670 #endif
00671 #endif
00672
00673 if (a->wds < b->wds)
00674 {
00675 c = a;
00676 a = b;
00677 b = c;
00678 }
00679 k = a->k;
00680 wa = a->wds;
00681 wb = b->wds;
00682 wc = wa + wb;
00683 if (wc > a->maxwds)
00684 {
00685 k++;
00686 }
00687 c = Balloc(k);
00688 for (x = c->x, xa = x + wc; x < xa; x++)
00689 {
00690 *x = 0;
00691 }
00692 xa = a->x;
00693 xae = xa + wa;
00694 xb = b->x;
00695 xbe = xb + wb;
00696 xc0 = c->x;
00697 #ifdef ULLong
00698 for (; xb < xbe; xc0++)
00699 {
00700 if ((y = *xb++))
00701 {
00702 x = xa;
00703 xc = xc0;
00704 carry = 0;
00705 do
00706 {
00707 z = *x++ * (ULLong)y + *xc + carry;
00708 carry = z >> 32;
00709 *xc++ = (unsigned int)(z & 0xFFFFFFFF);
00710 } while (x < xae);
00711 *xc = (unsigned int)carry;
00712 }
00713 }
00714 #else
00715 #ifdef Pack_32
00716 for (; xb < xbe; xb++, xc0++)
00717 {
00718 if (y = *xb & 0xffff)
00719 {
00720 x = xa;
00721 xc = xc0;
00722 carry = 0;
00723 do
00724 {
00725 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
00726 carry = z >> 16;
00727 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
00728 carry = z2 >> 16;
00729 Storeinc(xc, z2, z);
00730 } while (x < xae);
00731 *xc = carry;
00732 }
00733 if (y = *xb >> 16)
00734 {
00735 x = xa;
00736 xc = xc0;
00737 carry = 0;
00738 z2 = *xc;
00739 do
00740 {
00741 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
00742 carry = z >> 16;
00743 Storeinc(xc, z, z2);
00744 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
00745 carry = z2 >> 16;
00746 } while (x < xae);
00747 *xc = z2;
00748 }
00749 }
00750 #else
00751 for (; xb < xbe; xc0++)
00752 {
00753 if (y = *xb++)
00754 {
00755 x = xa;
00756 xc = xc0;
00757 carry = 0;
00758 do
00759 {
00760 z = *x++ * y + *xc + carry;
00761 carry = z >> 16;
00762 *xc++ = z & 0xffff;
00763 } while (x < xae);
00764 *xc = carry;
00765 }
00766 }
00767 #endif
00768 #endif
00769 for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc)
00770 {
00771 ;
00772 }
00773 c->wds = wc;
00774 return c;
00775 }
00776
00777 static Bigint *p5s;
00778
00779 static Bigint *pow5mult(Bigint *b, int k)
00780 {
00781 Bigint *b1, *p5, *p51;
00782 int i;
00783 static int p05[3] = { 5, 25, 125 };
00784
00785 if ((i = k & 3))
00786 {
00787 b = multadd(b, p05[i-1], 0);
00788 }
00789
00790 if (!(k >>= 2))
00791 {
00792 return b;
00793 }
00794 if (!(p5 = p5s))
00795 {
00796
00797 p5 = p5s = i2b(625);
00798 p5->next = 0;
00799 }
00800 for (;;)
00801 {
00802 if (k & 1)
00803 {
00804 b1 = mult(b, p5);
00805 Bfree(b);
00806 b = b1;
00807 }
00808 if (!(k >>= 1))
00809 {
00810 break;
00811 }
00812 if (!(p51 = p5->next))
00813 {
00814 p51 = p5->next = mult(p5,p5);
00815 p51->next = 0;
00816 }
00817 p5 = p51;
00818 }
00819 return b;
00820 }
00821
00822 static Bigint *lshift(Bigint *b, int k)
00823 {
00824 int i, k1, n, n1;
00825 Bigint *b1;
00826 ULong *x, *x1, *xe, z;
00827
00828 #ifdef Pack_32
00829 n = k >> 5;
00830 #else
00831 n = k >> 4;
00832 #endif
00833 k1 = b->k;
00834 n1 = n + b->wds + 1;
00835 for (i = b->maxwds; n1 > i; i <<= 1)
00836 {
00837 k1++;
00838 }
00839 b1 = Balloc(k1);
00840 x1 = b1->x;
00841 for (i = 0; i < n; i++)
00842 {
00843 *x1++ = 0;
00844 }
00845 x = b->x;
00846 xe = x + b->wds;
00847 #ifdef Pack_32
00848 if (k &= 0x1f)
00849 {
00850 k1 = 32 - k;
00851 z = 0;
00852 do
00853 {
00854 *x1++ = *x << k | z;
00855 z = *x++ >> k1;
00856 } while (x < xe);
00857 if ((*x1 = z))
00858 {
00859 ++n1;
00860 }
00861 }
00862 #else
00863 if (k &= 0xf)
00864 {
00865 k1 = 16 - k;
00866 z = 0;
00867 do
00868 {
00869 *x1++ = *x << k & 0xffff | z;
00870 z = *x++ >> k1;
00871 } while (x < xe);
00872 if (*x1 = z)
00873 {
00874 ++n1;
00875 }
00876 }
00877 #endif
00878 else
00879 {
00880 do
00881 {
00882 *x1++ = *x++;
00883 } while (x < xe);
00884 }
00885 b1->wds = n1 - 1;
00886 Bfree(b);
00887 return b1;
00888 }
00889
00890 static int cmp(Bigint *a, Bigint *b)
00891 {
00892 ULong *xa, *xa0, *xb, *xb0;
00893 int i, j;
00894
00895 i = a->wds;
00896 j = b->wds;
00897 if (i -= j)
00898 {
00899 return i;
00900 }
00901 xa0 = a->x;
00902 xa = xa0 + j;
00903 xb0 = b->x;
00904 xb = xb0 + j;
00905 for (;;)
00906 {
00907 if (*--xa != *--xb)
00908 {
00909 return *xa < *xb ? -1 : 1;
00910 }
00911 if (xa <= xa0)
00912 {
00913 break;
00914 }
00915 }
00916 return 0;
00917 }
00918
00919 static Bigint *diff(Bigint *a, Bigint *b)
00920 {
00921 Bigint *c;
00922 int i, wa, wb;
00923 ULong *xa, *xae, *xb, *xbe, *xc;
00924 #ifdef ULLong
00925 ULLong borrow, y;
00926 #else
00927 ULong borrow, y;
00928 #ifdef Pack_32
00929 ULong z;
00930 #endif
00931 #endif
00932
00933 i = cmp(a,b);
00934 if (!i)
00935 {
00936 c = Balloc(0);
00937 c->wds = 1;
00938 c->x[0] = 0;
00939 return c;
00940 }
00941 if (i < 0)
00942 {
00943 c = a;
00944 a = b;
00945 b = c;
00946 i = 1;
00947 }
00948 else
00949 {
00950 i = 0;
00951 }
00952 c = Balloc(a->k);
00953 c->sign = i;
00954 wa = a->wds;
00955 xa = a->x;
00956 xae = xa + wa;
00957 wb = b->wds;
00958 xb = b->x;
00959 xbe = xb + wb;
00960 xc = c->x;
00961 borrow = 0;
00962 #ifdef ULLong
00963 do
00964 {
00965 y = (ULLong)*xa++ - *xb++ - borrow;
00966 borrow = y >> 32 & (ULong)1;
00967 *xc++ = (unsigned int)(y & 0xFFFFFFFF);
00968 } while (xb < xbe);
00969 while (xa < xae)
00970 {
00971 y = *xa++ - borrow;
00972 borrow = y >> 32 & (ULong)1;
00973 *xc++ = (unsigned int)(y & 0xFFFFFFFF);
00974 }
00975 #else
00976 #ifdef Pack_32
00977 do
00978 {
00979 y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
00980 borrow = (y & 0x10000) >> 16;
00981 z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
00982 borrow = (z & 0x10000) >> 16;
00983 Storeinc(xc, z, y);
00984 } while (xb < xbe);
00985 while (xa < xae)
00986 {
00987 y = (*xa & 0xffff) - borrow;
00988 borrow = (y & 0x10000) >> 16;
00989 z = (*xa++ >> 16) - borrow;
00990 borrow = (z & 0x10000) >> 16;
00991 Storeinc(xc, z, y);
00992 }
00993 #else
00994 do
00995 {
00996 y = *xa++ - *xb++ - borrow;
00997 borrow = (y & 0x10000) >> 16;
00998 *xc++ = y & 0xffff;
00999 } while (xb < xbe);
01000 while (xa < xae)
01001 {
01002 y = *xa++ - borrow;
01003 borrow = (y & 0x10000) >> 16;
01004 *xc++ = y & 0xffff;
01005 }
01006 #endif
01007 #endif
01008 while (!*--xc)
01009 {
01010 wa--;
01011 }
01012 c->wds = wa;
01013 return c;
01014 }
01015
01016 double ulp(double x)
01017 {
01018 register Long L;
01019 double a;
01020
01021 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
01022 #ifndef Avoid_Underflow
01023 #ifndef Sudden_Underflow
01024 if (L > 0)
01025 {
01026 #endif
01027 #endif
01028 #ifdef IBM
01029 L |= Exp_msk1 >> 4;
01030 #endif
01031 word0(a) = L;
01032 word1(a) = 0;
01033 #ifndef Avoid_Underflow
01034 #ifndef Sudden_Underflow
01035 }
01036 else
01037 {
01038 L = -L >> Exp_shift;
01039 if (L < Exp_shift)
01040 {
01041 word0(a) = 0x80000 >> L;
01042 word1(a) = 0;
01043 }
01044 else
01045 {
01046 word0(a) = 0;
01047 L -= Exp_shift;
01048 word1(a) = L >= 31 ? 1 : 1 << 31 - L;
01049 }
01050 }
01051 #endif
01052 #endif
01053 return dval(a);
01054 }
01055
01056 static double b2d(Bigint *a, int *e)
01057 {
01058 ULong *xa, *xa0, w, y, z;
01059 int k;
01060 double d;
01061 #ifdef VAX
01062 ULong d0, d1;
01063 #else
01064 #define d0 word0(d)
01065 #define d1 word1(d)
01066 #endif
01067
01068 xa0 = a->x;
01069 xa = xa0 + a->wds;
01070 y = *--xa;
01071 k = hi0bits(y);
01072 *e = 32 - k;
01073 #ifdef Pack_32
01074 if (k < Ebits)
01075 {
01076 d0 = Exp_1 | y >> (Ebits - k);
01077 w = xa > xa0 ? *--xa : 0;
01078 d1 = y << ((32-Ebits) + k) | w >> (Ebits - k);
01079 goto ret_d;
01080 }
01081 z = xa > xa0 ? *--xa : 0;
01082 if (k -= Ebits)
01083 {
01084 d0 = Exp_1 | y << k | z >> (32 - k);
01085 y = xa > xa0 ? *--xa : 0;
01086 d1 = z << k | y >> (32 - k);
01087 }
01088 else
01089 {
01090 d0 = Exp_1 | y;
01091 d1 = z;
01092 }
01093 #else
01094 if (k < Ebits + 16)
01095 {
01096 z = xa > xa0 ? *--xa : 0;
01097 d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
01098 w = xa > xa0 ? *--xa : 0;
01099 y = xa > xa0 ? *--xa : 0;
01100 d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
01101 goto ret_d;
01102 }
01103 z = xa > xa0 ? *--xa : 0;
01104 w = xa > xa0 ? *--xa : 0;
01105 k -= Ebits + 16;
01106 d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
01107 y = xa > xa0 ? *--xa : 0;
01108 d1 = w << k + 16 | y << k;
01109 #endif
01110 ret_d:
01111 #ifdef VAX
01112 word0(d) = d0 >> 16 | d0 << 16;
01113 word1(d) = d1 >> 16 | d1 << 16;
01114 #else
01115 #undef d0
01116 #undef d1
01117 #endif
01118 return dval(d);
01119 }
01120
01121 static Bigint *d2b(double d, int *e, int *bits)
01122 {
01123 Bigint *b;
01124 int de, k;
01125 ULong *x, y, z;
01126 #ifndef Sudden_Underflow
01127 int i;
01128 #endif
01129 #ifdef VAX
01130 ULong d0, d1;
01131 d0 = word0(d) >> 16 | word0(d) << 16;
01132 d1 = word1(d) >> 16 | word1(d) << 16;
01133 #else
01134 #define d0 word0(d)
01135 #define d1 word1(d)
01136 #endif
01137
01138 #ifdef Pack_32
01139 b = Balloc(1);
01140 #else
01141 b = Balloc(2);
01142 #endif
01143 x = b->x;
01144
01145 z = d0 & Frac_mask;
01146 d0 &= 0x7fffffff;
01147 #ifdef Sudden_Underflow
01148 de = (int)(d0 >> Exp_shift);
01149 #ifndef IBM
01150 z |= Exp_msk11;
01151 #endif
01152 #else
01153 if ((de = (int)(d0 >> Exp_shift)))
01154 {
01155 z |= Exp_msk1;
01156 }
01157 #endif
01158 #ifdef Pack_32
01159 if ((y = d1))
01160 {
01161 if ((k = lo0bits(&y)))
01162 {
01163 x[0] = y | z << (32 - k);
01164 z >>= k;
01165 }
01166 else
01167 {
01168 x[0] = y;
01169 }
01170 #ifndef Sudden_Underflow
01171 i =
01172 #endif
01173 b->wds = (x[1] = z) ? 2 : 1;
01174 }
01175 else
01176 {
01177 k = lo0bits(&z);
01178 x[0] = z;
01179 #ifndef Sudden_Underflow
01180 i =
01181 #endif
01182 b->wds = 1;
01183 k += 32;
01184 }
01185 #else
01186 if (y = d1)
01187 {
01188 if (k = lo0bits(&y))
01189 {
01190 if (k >= 16)
01191 {
01192 x[0] = y | z << 32 - k & 0xffff;
01193 x[1] = z >> k - 16 & 0xffff;
01194 x[2] = z >> k;
01195 i = 2;
01196 }
01197 else
01198 {
01199 x[0] = y & 0xffff;
01200 x[1] = y >> 16 | z << 16 - k & 0xffff;
01201 x[2] = z >> k & 0xffff;
01202 x[3] = z >> k+16;
01203 i = 3;
01204 }
01205 }
01206 else
01207 {
01208 x[0] = y & 0xffff;
01209 x[1] = y >> 16;
01210 x[2] = z & 0xffff;
01211 x[3] = z >> 16;
01212 i = 3;
01213 }
01214 }
01215 else
01216 {
01217 k = lo0bits(&z);
01218 if (k >= 16)
01219 {
01220 x[0] = z;
01221 i = 0;
01222 }
01223 else
01224 {
01225 x[0] = z & 0xffff;
01226 x[1] = z >> 16;
01227 i = 1;
01228 }
01229 k += 32;
01230 }
01231 while (!x[i])
01232 {
01233 --i;
01234 }
01235 b->wds = i + 1;
01236 #endif
01237 #ifndef Sudden_Underflow
01238 if (de)
01239 {
01240 #endif
01241 #ifdef IBM
01242 *e = (de - Bias - (P-1) << 2) + k;
01243 *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask);
01244 #else
01245 *e = de - Bias - (P-1) + k;
01246 *bits = P - k;
01247 #endif
01248 #ifndef Sudden_Underflow
01249 }
01250 else
01251 {
01252 *e = de - Bias - (P-1) + 1 + k;
01253 #ifdef Pack_32
01254 *bits = 32*i - hi0bits(x[i-1]);
01255 #else
01256 *bits = (i+2)*16 - hi0bits(x[i]);
01257 #endif
01258 }
01259 #endif
01260 return b;
01261 }
01262 #undef d0
01263 #undef d1
01264
01265 static double ratio(Bigint *a, Bigint *b)
01266 {
01267 double da, db;
01268 int k, ka, kb;
01269
01270 dval(da) = b2d(a, &ka);
01271 dval(db) = b2d(b, &kb);
01272 #ifdef Pack_32
01273 k = ka - kb + 32*(a->wds - b->wds);
01274 #else
01275 k = ka - kb + 16*(a->wds - b->wds);
01276 #endif
01277 #ifdef IBM
01278 if (k > 0)
01279 {
01280 word0(da) += (k >> 2)*Exp_msk1;
01281 if (k &= 3)
01282 {
01283 dval(da) *= 1 << k;
01284 }
01285 }
01286 else
01287 {
01288 k = -k;
01289 word0(db) += (k >> 2)*Exp_msk1;
01290 if (k &= 3)
01291 {
01292 dval(db) *= 1 << k;
01293 }
01294 }
01295 #else
01296 if (k > 0)
01297 {
01298 word0(da) += k*Exp_msk1;
01299 }
01300 else
01301 {
01302 k = -k;
01303 word0(db) += k*Exp_msk1;
01304 }
01305 #endif
01306 return dval(da) / dval(db);
01307 }
01308
01309 static CONST double tens[] =
01310 {
01311 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
01312 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
01313 1e20, 1e21, 1e22
01314 #ifdef VAX
01315 , 1e23, 1e24
01316 #endif
01317 };
01318
01319 static CONST double
01320 #ifdef IEEE_Arith
01321 bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
01322 static CONST double tinytens[] =
01323 {
01324 1e-16, 1e-32, 1e-64, 1e-128,
01325 #ifdef Avoid_Underflow
01326 9007199254740992.*9007199254740992.e-256
01327
01328 #else
01329 1e-256
01330 #endif
01331 };
01332
01333
01334
01335 #define Scale_Bit 0x10
01336 #define n_bigtens 5
01337 #else
01338 #ifdef IBM
01339 bigtens[] = { 1e16, 1e32, 1e64 };
01340 static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
01341 #define n_bigtens 3
01342 #else
01343 bigtens[] = { 1e16, 1e32 };
01344 static CONST double tinytens[] = { 1e-16, 1e-32 };
01345 #define n_bigtens 2
01346 #endif
01347 #endif
01348
01349 double mux_strtod(CONST char *s00, char **se)
01350 {
01351 #ifdef Avoid_Underflow
01352 int scale;
01353 #endif
01354 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
01355 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
01356 CONST char *s, *s0, *s1;
01357 double aadj, aadj1, adj, rv, rv0;
01358 Long L;
01359 ULong y, z;
01360 Bigint *bb = NULL, *bb1 = NULL, *bd = NULL, *bd0 = NULL, *bs = NULL;
01361 Bigint *delta = NULL;
01362 #ifdef SET_INEXACT
01363 int inexact, oldinexact;
01364 #endif
01365 #ifdef Honor_FLT_ROUNDS
01366 int rounding;
01367 #endif
01368
01369 sign = nz0 = nz = 0;
01370 dval(rv) = 0.;
01371 for (s = s00;;s++)
01372 {
01373 switch (*s)
01374 {
01375 case '-':
01376 sign = 1;
01377
01378 case '+':
01379 if (*++s)
01380 goto break2;
01381
01382 case 0:
01383 goto ret0;
01384 case '\t':
01385 case '\n':
01386 case '\v':
01387 case '\f':
01388 case '\r':
01389 case ' ':
01390 continue;
01391 default:
01392 goto break2;
01393 }
01394 }
01395 break2:
01396 if (*s == '0')
01397 {
01398 nz0 = 1;
01399 while (*++s == '0')
01400 {
01401 ;
01402 }
01403 if (!*s)
01404 {
01405 goto ret;
01406 }
01407 }
01408 s0 = s;
01409 y = z = 0;
01410 for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
01411 {
01412 if (nd < 9)
01413 {
01414 y = 10*y + c - '0';
01415 }
01416 else if (nd < 16)
01417 {
01418 z = 10*z + c - '0';
01419 }
01420 }
01421 nd0 = nd;
01422 if (c == '.')
01423 {
01424 c = *++s;
01425 if (!nd)
01426 {
01427 for (; c == '0'; c = *++s)
01428 {
01429 nz++;
01430 }
01431 if (c > '0' && c <= '9')
01432 {
01433 s0 = s;
01434 nf += nz;
01435 nz = 0;
01436 goto have_dig;
01437 }
01438 goto dig_done;
01439 }
01440 for (; c >= '0' && c <= '9'; c = *++s)
01441 {
01442 have_dig:
01443 nz++;
01444 if (c -= '0')
01445 {
01446 nf += nz;
01447 for (i = 1; i < nz; i++)
01448 {
01449 if (nd++ < 9)
01450 {
01451 y *= 10;
01452 }
01453 else if (nd <= DBL_DIG + 1)
01454 {
01455 z *= 10;
01456 }
01457 }
01458 if (nd++ < 9)
01459 {
01460 y = 10*y + c;
01461 }
01462 else if (nd <= DBL_DIG + 1)
01463 {
01464 z = 10*z + c;
01465 }
01466 nz = 0;
01467 }
01468 }
01469 }
01470 dig_done:
01471 e = 0;
01472 if (c == 'e' || c == 'E')
01473 {
01474 if (!nd && !nz && !nz0)
01475 {
01476 goto ret0;
01477 }
01478 s00 = s;
01479 esign = 0;
01480 switch (c = *++s)
01481 {
01482 case '-':
01483 esign = 1;
01484 case '+':
01485 c = *++s;
01486 }
01487 if (c >= '0' && c <= '9')
01488 {
01489 while (c == '0')
01490 {
01491 c = *++s;
01492 }
01493 if (c > '0' && c <= '9')
01494 {
01495 L = c - '0';
01496 s1 = s;
01497 while ((c = *++s) >= '0' && c <= '9')
01498 {
01499 L = 10*L + c - '0';
01500 }
01501 if (s - s1 > 8 || L > 19999)
01502 {
01503
01504
01505
01506 e = 19999;
01507 }
01508 else
01509 {
01510 e = (int)L;
01511 }
01512 if (esign)
01513 {
01514 e = -e;
01515 }
01516 }
01517 else
01518 {
01519 e = 0;
01520 }
01521 }
01522 else
01523 {
01524 s = s00;
01525 }
01526 }
01527 if (!nd)
01528 {
01529 if (!nz && !nz0)
01530 {
01531 ret0:
01532 s = s00;
01533 sign = 0;
01534 }
01535 goto ret;
01536 }
01537 e1 = e -= nf;
01538
01539
01540
01541
01542
01543
01544 if (!nd0)
01545 {
01546 nd0 = nd;
01547 }
01548 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
01549 dval(rv) = y;
01550 if (k > 9)
01551 {
01552 #ifdef SET_INEXACT
01553 if (k > DBL_DIG)
01554 {
01555 oldinexact = get_inexact();
01556 }
01557 #endif
01558 dval(rv) = tens[k - 9] * dval(rv) + z;
01559 }
01560 bd0 = 0;
01561 if (nd <= DBL_DIG
01562 #ifndef RND_PRODQUOT
01563 #ifndef Honor_FLT_ROUNDS
01564 && Flt_Rounds == 1
01565 #endif
01566 #endif
01567 )
01568 {
01569 if (!e)
01570 {
01571 goto ret;
01572 }
01573 if (e > 0)
01574 {
01575 if (e <= Ten_pmax)
01576 {
01577 #ifdef VAX
01578 goto vax_ovfl_check;
01579 #else
01580 #ifdef Honor_FLT_ROUNDS
01581
01582 if (sign)
01583 {
01584 rv = -rv;
01585 sign = 0;
01586 }
01587 #endif
01588 rounded_product(dval(rv), tens[e]);
01589 goto ret;
01590 #endif
01591 }
01592 i = DBL_DIG - nd;
01593 if (e <= Ten_pmax + i)
01594 {
01595
01596
01597
01598 #ifdef Honor_FLT_ROUNDS
01599
01600 if (sign)
01601 {
01602 rv = -rv;
01603 sign = 0;
01604 }
01605 #endif
01606 e -= i;
01607 dval(rv) *= tens[i];
01608 #ifdef VAX
01609
01610
01611
01612 vax_ovfl_check:
01613 word0(rv) -= P*Exp_msk1;
01614 rounded_product(dval(rv), tens[e]);
01615 if ((word0(rv) & Exp_mask)
01616 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
01617 {
01618 goto ovfl;
01619 }
01620 word0(rv) += P*Exp_msk1;
01621 #else
01622 rounded_product(dval(rv), tens[e]);
01623 #endif
01624 goto ret;
01625 }
01626 }
01627 #ifndef Inaccurate_Divide
01628 else if (e >= -Ten_pmax)
01629 {
01630 #ifdef Honor_FLT_ROUNDS
01631
01632 if (sign)
01633 {
01634 rv = -rv;
01635 sign = 0;
01636 }
01637 #endif
01638 rounded_quotient(dval(rv), tens[-e]);
01639 goto ret;
01640 }
01641 #endif
01642 }
01643 e1 += nd - k;
01644
01645 #ifdef IEEE_Arith
01646 #ifdef SET_INEXACT
01647 inexact = 1;
01648 if (k <= DBL_DIG)
01649 {
01650 oldinexact = get_inexact();
01651 }
01652 #endif
01653 #ifdef Avoid_Underflow
01654 scale = 0;
01655 #endif
01656 #ifdef Honor_FLT_ROUNDS
01657 if ((rounding = Flt_Rounds) >= 2)
01658 {
01659 if (sign)
01660 {
01661 rounding = rounding == 2 ? 0 : 2;
01662 }
01663 else
01664 {
01665 if (rounding != 2)
01666 {
01667 rounding = 0;
01668 }
01669 }
01670 }
01671 #endif
01672 #endif
01673
01674
01675
01676 if (e1 > 0)
01677 {
01678 if ((i = e1 & 15))
01679 {
01680 dval(rv) *= tens[i];
01681 }
01682 if (e1 &= ~15)
01683 {
01684 if (e1 > DBL_MAX_10_EXP)
01685 {
01686 ovfl:
01687
01688 #ifdef IEEE_Arith
01689 #ifdef Honor_FLT_ROUNDS
01690 switch (rounding)
01691 {
01692 case 0:
01693 case 3:
01694 word0(rv) = Big0;
01695 word1(rv) = Big1;
01696 break;
01697 default:
01698 word0(rv) = Exp_mask;
01699 word1(rv) = 0;
01700 }
01701 #else
01702 word0(rv) = Exp_mask;
01703 word1(rv) = 0;
01704 #endif
01705 #ifdef SET_INEXACT
01706
01707 dval(rv0) = 1e300;
01708 dval(rv0) *= dval(rv0);
01709 #endif
01710 #else
01711 word0(rv) = Big0;
01712 word1(rv) = Big1;
01713 #endif
01714 if (bd0)
01715 {
01716 goto retfree;
01717 }
01718 goto ret;
01719 }
01720 e1 >>= 4;
01721 for (j = 0; e1 > 1; j++, e1 >>= 1)
01722 {
01723 if (e1 & 1)
01724 {
01725 dval(rv) *= bigtens[j];
01726 }
01727 }
01728
01729 word0(rv) -= P*Exp_msk1;
01730 dval(rv) *= bigtens[j];
01731 if ((z = word0(rv) & Exp_mask)
01732 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
01733 {
01734 goto ovfl;
01735 }
01736 if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
01737 {
01738
01739
01740 word0(rv) = Big0;
01741 word1(rv) = Big1;
01742 }
01743 else
01744 {
01745 word0(rv) += P*Exp_msk1;
01746 }
01747 }
01748 }
01749 else if (e1 < 0)
01750 {
01751 e1 = -e1;
01752 if ((i = e1 & 15))
01753 {
01754 dval(rv) /= tens[i];
01755 }
01756 if (e1 >>= 4)
01757 {
01758 if (e1 >= 1 << n_bigtens)
01759 {
01760 goto undfl;
01761 }
01762 #ifdef Avoid_Underflow
01763 if (e1 & Scale_Bit)
01764 {
01765 scale = 2*P;
01766 }
01767 for (j = 0; e1 > 0; j++, e1 >>= 1)
01768 {
01769 if (e1 & 1)
01770 {
01771 dval(rv) *= tinytens[j];
01772 }
01773 }
01774 if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask)
01775 >> Exp_shift)) > 0)
01776 {
01777
01778 if (j >= 32)
01779 {
01780 word1(rv) = 0;
01781 if (j >= 53)
01782 {
01783 word0(rv) = (P+2)*Exp_msk1;
01784 }
01785 else
01786 {
01787 word0(rv) &= 0xffffffff << (j-32);
01788 }
01789 }
01790 else
01791 {
01792 word1(rv) &= 0xffffffff << j;
01793 }
01794 }
01795 #else
01796 for (j = 0; e1 > 1; j++, e1 >>= 1)
01797 {
01798 if (e1 & 1)
01799 {
01800 dval(rv) *= tinytens[j];
01801 }
01802 }
01803
01804 dval(rv0) = dval(rv);
01805 dval(rv) *= tinytens[j];
01806 if (!dval(rv))
01807 {
01808 dval(rv) = 2.*dval(rv0);
01809 dval(rv) *= tinytens[j];
01810 #endif
01811 if (!dval(rv))
01812 {
01813 undfl:
01814 dval(rv) = 0.;
01815 if (bd0)
01816 {
01817 goto retfree;
01818 }
01819 goto ret;
01820 }
01821 #ifndef Avoid_Underflow
01822 word0(rv) = Tiny0;
01823 word1(rv) = Tiny1;
01824
01825
01826
01827 }
01828 #endif
01829 }
01830 }
01831
01832
01833
01834
01835
01836 bd0 = s2b(s0, nd0, nd, y);
01837
01838 for (;;)
01839 {
01840 bd = Balloc(bd0->k);
01841 Bcopy(bd, bd0);
01842 bb = d2b(dval(rv), &bbe, &bbbits);
01843 bs = i2b(1);
01844
01845 if (e >= 0)
01846 {
01847 bb2 = bb5 = 0;
01848 bd2 = bd5 = e;
01849 }
01850 else
01851 {
01852 bb2 = bb5 = -e;
01853 bd2 = bd5 = 0;
01854 }
01855 if (bbe >= 0)
01856 {
01857 bb2 += bbe;
01858 }
01859 else
01860 {
01861 bd2 -= bbe;
01862 }
01863 bs2 = bb2;
01864 #ifdef Honor_FLT_ROUNDS
01865 if (rounding != 1)
01866 {
01867 bs2++;
01868 }
01869 #endif
01870 #ifdef Avoid_Underflow
01871 j = bbe - scale;
01872 i = j + bbbits - 1;
01873 if (i < Emin)
01874 {
01875 j += P - Emin;
01876 }
01877 else
01878 {
01879 j = P + 1 - bbbits;
01880 }
01881 #else
01882 #ifdef Sudden_Underflow
01883 #ifdef IBM
01884 j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
01885 #else
01886 j = P + 1 - bbbits;
01887 #endif
01888 #else
01889 j = bbe;
01890 i = j + bbbits - 1;
01891 if (i < Emin)
01892 {
01893 j += P - Emin;
01894 }
01895 else
01896 {
01897 j = P + 1 - bbbits;
01898 }
01899 #endif
01900 #endif
01901 bb2 += j;
01902 bd2 += j;
01903 #ifdef Avoid_Underflow
01904 bd2 += scale;
01905 #endif
01906 i = bb2 < bd2 ? bb2 : bd2;
01907 if (i > bs2)
01908 {
01909 i = bs2;
01910 }
01911 if (i > 0)
01912 {
01913 bb2 -= i;
01914 bd2 -= i;
01915 bs2 -= i;
01916 }
01917 if (bb5 > 0)
01918 {
01919 bs = pow5mult(bs, bb5);
01920 bb1 = mult(bs, bb);
01921 Bfree(bb);
01922 bb = bb1;
01923 }
01924 if (bb2 > 0)
01925 {
01926 bb = lshift(bb, bb2);
01927 }
01928 if (bd5 > 0)
01929 {
01930 bd = pow5mult(bd, bd5);
01931 }
01932 if (bd2 > 0)
01933 {
01934 bd = lshift(bd, bd2);
01935 }
01936 if (bs2 > 0)
01937 {
01938 bs = lshift(bs, bs2);
01939 }
01940 delta = diff(bb, bd);
01941 dsign = delta->sign;
01942 delta->sign = 0;
01943 i = cmp(delta, bs);
01944 #ifdef Honor_FLT_ROUNDS
01945 if (rounding != 1)
01946 {
01947 if (i < 0)
01948 {
01949
01950 if (!delta->x[0] && delta->wds <= 1)
01951 {
01952
01953 #ifdef SET_INEXACT
01954 inexact = 0;
01955 #endif
01956 break;
01957 }
01958 if (rounding)
01959 {
01960 if (dsign)
01961 {
01962 adj = 1.;
01963 goto apply_adj;
01964 }
01965 }
01966 else if (!dsign)
01967 {
01968 adj = -1.;
01969 if ( !word1(rv)
01970 && !(word0(rv) & Frac_mask))
01971 {
01972 y = word0(rv) & Exp_mask;
01973 #ifdef Avoid_Underflow
01974 if (!scale || y > 2*P*Exp_msk1)
01975 #else
01976 if (y)
01977 #endif
01978 {
01979 delta = lshift(delta,Log2P);
01980 if (cmp(delta, bs) <= 0)
01981 {
01982 adj = -0.5;
01983 }
01984 }
01985 }
01986 apply_adj:
01987 #ifdef Avoid_Underflow
01988 if (scale && (y = word0(rv) & Exp_mask)
01989 <= 2*P*Exp_msk1)
01990 {
01991 word0(adj) += (2*P+1)*Exp_msk1 - y;
01992 }
01993 #else
01994 #ifdef Sudden_Underflow
01995 if ((word0(rv) & Exp_mask) <=
01996 P*Exp_msk1)
01997 {
01998 word0(rv) += P*Exp_msk1;
01999 dval(rv) += adj*ulp(dval(rv));
02000 word0(rv) -= P*Exp_msk1;
02001 }
02002 else
02003 #endif
02004 #endif
02005 dval(rv) += adj*ulp(dval(rv));
02006 }
02007 break;
02008 }
02009 adj = ratio(delta, bs);
02010 if (adj < 1.)
02011 {
02012 adj = 1.;
02013 }
02014 if (adj <= 0x7ffffffe)
02015 {
02016
02017 y = adj;
02018 if (y != adj)
02019 {
02020 if (!((rounding>>1) ^ dsign))
02021 {
02022 y++;
02023 }
02024 adj = y;
02025 }
02026 }
02027 #ifdef Avoid_Underflow
02028 if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
02029 {
02030 word0(adj) += (2*P+1)*Exp_msk1 - y;
02031 }
02032 #else
02033 #ifdef Sudden_Underflow
02034 if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
02035 {
02036 word0(rv) += P*Exp_msk1;
02037 adj *= ulp(dval(rv));
02038 if (dsign)
02039 {
02040 dval(rv) += adj;
02041 }
02042 else
02043 {
02044 dval(rv) -= adj;
02045 }
02046 word0(rv) -= P*Exp_msk1;
02047 goto cont;
02048 }
02049 #endif
02050 #endif
02051 adj *= ulp(dval(rv));
02052 if (dsign)
02053 {
02054 dval(rv) += adj;
02055 }
02056 else
02057 {
02058 dval(rv) -= adj;
02059 }
02060 goto cont;
02061 }
02062 #endif
02063
02064 if (i < 0)
02065 {
02066
02067
02068
02069 if (dsign || word1(rv) || word0(rv) & Bndry_mask
02070 #ifdef IEEE_Arith
02071 #ifdef Avoid_Underflow
02072 || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1
02073 #else
02074 || (word0(rv) & Exp_mask) <= Exp_msk1
02075 #endif
02076 #endif
02077 )
02078 {
02079 #ifdef SET_INEXACT
02080 if (!delta->x[0] && delta->wds <= 1)
02081 {
02082 inexact = 0;
02083 }
02084 #endif
02085 break;
02086 }
02087 if (!delta->x[0] && delta->wds <= 1)
02088 {
02089
02090 #ifdef SET_INEXACT
02091 inexact = 0;
02092 #endif
02093 break;
02094 }
02095 delta = lshift(delta,Log2P);
02096 if (cmp(delta, bs) > 0)
02097 {
02098 goto drop_down;
02099 }
02100 break;
02101 }
02102 if (i == 0)
02103 {
02104
02105 if (dsign)
02106 {
02107 if ((word0(rv) & Bndry_mask1) == Bndry_mask1
02108 && word1(rv) == (
02109 #ifdef Avoid_Underflow
02110 (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
02111 ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
02112 #endif
02113 0xffffffff))
02114 {
02115
02116 word0(rv) = (word0(rv) & Exp_mask)
02117 + Exp_msk1
02118 #ifdef IBM
02119 | Exp_msk1 >> 4
02120 #endif
02121 ;
02122 word1(rv) = 0;
02123 #ifdef Avoid_Underflow
02124 dsign = 0;
02125 #endif
02126 break;
02127 }
02128 }
02129 else if (!(word0(rv) & Bndry_mask) && !word1(rv))
02130 {
02131 drop_down:
02132
02133 #ifdef Sudden_Underflow
02134 L = word0(rv) & Exp_mask;
02135 #ifdef IBM
02136 if (L < Exp_msk1)
02137 #else
02138 #ifdef Avoid_Underflow
02139 if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
02140 #else
02141 if (L <= Exp_msk1)
02142 #endif
02143 #endif
02144 {
02145 goto undfl;
02146 }
02147 L -= Exp_msk1;
02148 #else
02149 #ifdef Avoid_Underflow
02150 if (scale)
02151 {
02152 L = word0(rv) & Exp_mask;
02153 if (L <= (2*P+1)*Exp_msk1)
02154 {
02155 if (L > (P+2)*Exp_msk1)
02156 {
02157
02158
02159 break;
02160 }
02161
02162 goto undfl;
02163 }
02164 }
02165 #endif
02166 L = (word0(rv) & Exp_mask) - Exp_msk1;
02167 #endif
02168 word0(rv) = L | Bndry_mask1;
02169 word1(rv) = 0xffffffff;
02170 #ifdef IBM
02171 goto cont;
02172 #else
02173 break;
02174 #endif
02175 }
02176 #ifndef ROUND_BIASED
02177 if (!(word1(rv) & LSB))
02178 {
02179 break;
02180 }
02181 #endif
02182 if (dsign)
02183 {
02184 dval(rv) += ulp(dval(rv));
02185 }
02186 #ifndef ROUND_BIASED
02187 else
02188 {
02189 dval(rv) -= ulp(dval(rv));
02190 #ifndef Sudden_Underflow
02191 if (!dval(rv))
02192 {
02193 goto undfl;
02194 }
02195 #endif
02196 }
02197 #ifdef Avoid_Underflow
02198 dsign = 1 - dsign;
02199 #endif
02200 #endif
02201 break;
02202 }
02203 if ((aadj = ratio(delta, bs)) <= 2.)
02204 {
02205 if (dsign)
02206 {
02207 aadj = aadj1 = 1.;
02208 }
02209 else if (word1(rv) || word0(rv) & Bndry_mask)
02210 {
02211 #ifndef Sudden_Underflow
02212 if (word1(rv) == Tiny1 && !word0(rv))
02213 {
02214 goto undfl;
02215 }
02216 #endif
02217 aadj = 1.;
02218 aadj1 = -1.;
02219 }
02220 else
02221 {
02222
02223
02224
02225 if (aadj < 2./FLT_RADIX)
02226 {
02227 aadj = 1./FLT_RADIX;
02228 }
02229 else
02230 {
02231 aadj *= 0.5;
02232 }
02233 aadj1 = -aadj;
02234 }
02235 }
02236 else
02237 {
02238 aadj *= 0.5;
02239 aadj1 = dsign ? aadj : -aadj;
02240 #ifdef Check_FLT_ROUNDS
02241 switch (Rounding)
02242 {
02243 case 2:
02244 aadj1 -= 0.5;
02245 break;
02246 case 0:
02247 case 3:
02248 aadj1 += 0.5;
02249 }
02250 #else
02251 if (Flt_Rounds == 0)
02252 {
02253 aadj1 += 0.5;
02254 }
02255 #endif
02256 }
02257 y = word0(rv) & Exp_mask;
02258
02259
02260
02261 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1))
02262 {
02263 dval(rv0) = dval(rv);
02264 word0(rv) -= P*Exp_msk1;
02265 adj = aadj1 * ulp(dval(rv));
02266 dval(rv) += adj;
02267 if ((word0(rv) & Exp_mask) >=
02268 Exp_msk1*(DBL_MAX_EXP+Bias-P))
02269 {
02270 if (word0(rv0) == Big0 && word1(rv0) == Big1)
02271 {
02272 goto ovfl;
02273 }
02274 word0(rv) = Big0;
02275 word1(rv) = Big1;
02276 goto cont;
02277 }
02278 else
02279 {
02280 word0(rv) += P*Exp_msk1;
02281 }
02282 }
02283 else
02284 {
02285 #ifdef Avoid_Underflow
02286 if (scale && y <= 2*P*Exp_msk1)
02287 {
02288 if (aadj <= 0x7fffffff)
02289 {
02290 if ((z = (ULong)aadj) <= 0)
02291 {
02292 z = 1;
02293 }
02294 aadj = z;
02295 aadj1 = dsign ? aadj : -aadj;
02296 }
02297 word0(aadj1) += (2*P+1)*Exp_msk1 - y;
02298 }
02299 adj = aadj1 * ulp(dval(rv));
02300 dval(rv) += adj;
02301 #else
02302 #ifdef Sudden_Underflow
02303 if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
02304 {
02305 dval(rv0) = dval(rv);
02306 word0(rv) += P*Exp_msk1;
02307 adj = aadj1 * ulp(dval(rv));
02308 dval(rv) += adj;
02309 #ifdef IBM
02310 if ((word0(rv) & Exp_mask) < P*Exp_msk1)
02311 #else
02312 if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
02313 #endif
02314 {
02315 if (word0(rv0) == Tiny0
02316 && word1(rv0) == Tiny1)
02317 {
02318 goto undfl;
02319 }
02320 word0(rv) = Tiny0;
02321 word1(rv) = Tiny1;
02322 goto cont;
02323 }
02324 else
02325 {
02326 word0(rv) -= P*Exp_msk1;
02327 }
02328 }
02329 else
02330 {
02331 adj = aadj1 * ulp(dval(rv));
02332 dval(rv) += adj;
02333 }
02334 #else
02335
02336
02337
02338
02339
02340
02341
02342 if (y <= (P-1)*Exp_msk1 && aadj > 1.)
02343 {
02344 aadj1 = (double)(int)(aadj + 0.5);
02345 if (!dsign)
02346 {
02347 aadj1 = -aadj1;
02348 }
02349 }
02350 adj = aadj1 * ulp(dval(rv));
02351 dval(rv) += adj;
02352 #endif
02353 #endif
02354 }
02355 z = word0(rv) & Exp_mask;
02356 #ifndef SET_INEXACT
02357 #ifdef Avoid_Underflow
02358 if (!scale)
02359 #endif
02360 if (y == z)
02361 {
02362
02363 L = (Long)aadj;
02364 aadj -= L;
02365
02366 if (dsign || word1(rv) || word0(rv) & Bndry_mask)
02367 {
02368 if (aadj < .4999999 || aadj > .5000001)
02369 {
02370 break;
02371 }
02372 }
02373 else if (aadj < .4999999/FLT_RADIX)
02374 {
02375 break;
02376 }
02377 }
02378 #endif
02379 cont:
02380 Bfree(bb);
02381 Bfree(bd);
02382 Bfree(bs);
02383 Bfree(delta);
02384 }
02385 #ifdef SET_INEXACT
02386 if (inexact)
02387 {
02388 if (!oldinexact)
02389 {
02390 word0(rv0) = Exp_1 + (70 << Exp_shift);
02391 word1(rv0) = 0;
02392 dval(rv0) += 1.;
02393 }
02394 }
02395 else if (!oldinexact)
02396 {
02397 clear_inexact();
02398 }
02399 #endif
02400 #ifdef Avoid_Underflow
02401 if (scale)
02402 {
02403 word0(rv0) = Exp_1 - 2*P*Exp_msk1;
02404 word1(rv0) = 0;
02405 dval(rv) *= dval(rv0);
02406 }
02407 #endif
02408 #ifdef SET_INEXACT
02409 if (inexact && !(word0(rv) & Exp_mask))
02410 {
02411
02412 dval(rv0) = 1e-300;
02413 dval(rv0) *= dval(rv0);
02414 }
02415 #endif
02416 retfree:
02417 Bfree(bb);
02418 Bfree(bd);
02419 Bfree(bs);
02420 Bfree(bd0);
02421 Bfree(delta);
02422 ret:
02423 if (se)
02424 {
02425 *se = (char *)s;
02426 }
02427 return sign ? -dval(rv) : dval(rv);
02428 }
02429
02430 static int quorem(Bigint *b, Bigint *S)
02431 {
02432 int n;
02433 ULong *bx, *bxe, q, *sx, *sxe;
02434 #ifdef ULLong
02435 ULLong borrow, carry, y, ys;
02436 #else
02437 ULong borrow, carry, y, ys;
02438 #ifdef Pack_32
02439 ULong si, z, zs;
02440 #endif
02441 #endif
02442
02443 n = S->wds;
02444 if (b->wds < n)
02445 {
02446 return 0;
02447 }
02448 sx = S->x;
02449 sxe = sx + --n;
02450 bx = b->x;
02451 bxe = bx + n;
02452 q = *bxe / (*sxe + 1);
02453 if (q)
02454 {
02455 borrow = 0;
02456 carry = 0;
02457 do
02458 {
02459 #ifdef ULLong
02460 ys = *sx++ * (ULLong)q + carry;
02461 carry = ys >> 32;
02462 y = *bx - (ys & FFFFFFFF) - borrow;
02463 borrow = y >> 32 & (ULong)1;
02464 *bx++ = (unsigned int)(y & 0xFFFFFFFF);
02465 #else
02466 #ifdef Pack_32
02467 si = *sx++;
02468 ys = (si & 0xffff) * q + carry;
02469 zs = (si >> 16) * q + (ys >> 16);
02470 carry = zs >> 16;
02471 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
02472 borrow = (y & 0x10000) >> 16;
02473 z = (*bx >> 16) - (zs & 0xffff) - borrow;
02474 borrow = (z & 0x10000) >> 16;
02475 Storeinc(bx, z, y);
02476 #else
02477 ys = *sx++ * q + carry;
02478 carry = ys >> 16;
02479 y = *bx - (ys & 0xffff) - borrow;
02480 borrow = (y & 0x10000) >> 16;
02481 *bx++ = y & 0xffff;
02482 #endif
02483 #endif
02484 } while (sx <= sxe);
02485 if (!*bxe)
02486 {
02487 bx = b->x;
02488 while (--bxe > bx && !*bxe)
02489 {
02490 --n;
02491 }
02492 b->wds = n;
02493 }
02494 }
02495 if (cmp(b, S) >= 0)
02496 {
02497 q++;
02498 borrow = 0;
02499 carry = 0;
02500 bx = b->x;
02501 sx = S->x;
02502 do
02503 {
02504 #ifdef ULLong
02505 ys = *sx++ + carry;
02506 carry = ys >> 32;
02507 y = *bx - (ys & 0xFFFFFFFF) - borrow;
02508 borrow = y >> 32 & (ULong)1;
02509 *bx++ = (unsigned int)(y & 0xFFFFFFFF);
02510 #else
02511 #ifdef Pack_32
02512 si = *sx++;
02513 ys = (si & 0xffff) + carry;
02514 zs = (si >> 16) + (ys >> 16);
02515 carry = zs >> 16;
02516 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
02517 borrow = (y & 0x10000) >> 16;
02518 z = (*bx >> 16) - (zs & 0xffff) - borrow;
02519 borrow = (z & 0x10000) >> 16;
02520 Storeinc(bx, z, y);
02521 #else
02522 ys = *sx++ + carry;
02523 carry = ys >> 16;
02524 y = *bx - (ys & 0xffff) - borrow;
02525 borrow = (y & 0x10000) >> 16;
02526 *bx++ = y & 0xffff;
02527 #endif
02528 #endif
02529 } while (sx <= sxe);
02530 bx = b->x;
02531 bxe = bx + n;
02532 if (!*bxe)
02533 {
02534 while (--bxe > bx && !*bxe)
02535 {
02536 --n;
02537 }
02538 b->wds = n;
02539 }
02540 }
02541 return q;
02542 }
02543
02544 static char *dtoa_result;
02545
02546 static char *rv_alloc(unsigned int i)
02547 {
02548 unsigned int j, k, *r;
02549
02550 j = sizeof(ULong);
02551 for (k = 0;
02552 sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
02553 j <<= 1)
02554 {
02555 k++;
02556 }
02557 r = (unsigned int*)Balloc(k);
02558 *r = k;
02559 dtoa_result = (char *)(r+1);
02560 return dtoa_result;
02561 }
02562
02563 static char *nrv_alloc(char *s, char **rve, int n)
02564 {
02565 char *rv, *t;
02566
02567 t = rv = rv_alloc(n);
02568 while ((*t = *s++))
02569 {
02570 t++;
02571 }
02572 if (rve)
02573 {
02574 *rve = t;
02575 }
02576 return rv;
02577 }
02578
02579
02580
02581 static void freedtoa(char *s)
02582 {
02583 Bigint *b = (Bigint *)((int *)s - 1);
02584 b->maxwds = 1 << (b->k = *(int*)b);
02585 Bfree(b);
02586 if (s == dtoa_result)
02587 {
02588 dtoa_result = 0;
02589 }
02590 }
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626 char *mux_dtoa(double d, int mode, int ndigits, int *decpt, int *sign,
02627 char **rve)
02628 {
02629
02630
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663 int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0 = 0, ilim1 = 0,
02664 j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
02665 spec_case, try_quick;
02666 Long L;
02667 #ifndef Sudden_Underflow
02668 int denorm;
02669 ULong x;
02670 #endif
02671 Bigint *b = NULL, *b1 = NULL, *delta = NULL, *mlo = NULL, *mhi = NULL, *S = NULL;
02672 double d2, ds, eps;
02673 char *s, *s0;
02674 #ifdef Honor_FLT_ROUNDS
02675 int rounding;
02676 #endif
02677 #ifdef SET_INEXACT
02678 int inexact, oldinexact;
02679 #endif
02680
02681 if (dtoa_result)
02682 {
02683 freedtoa(dtoa_result);
02684 dtoa_result = 0;
02685 }
02686
02687 if (word0(d) & Sign_bit)
02688 {
02689
02690 *sign = 1;
02691 word0(d) &= ~Sign_bit;
02692 }
02693 else
02694 {
02695 *sign = 0;
02696 }
02697
02698 #if defined(IEEE_Arith) + defined(VAX)
02699 #ifdef IEEE_Arith
02700 if ((word0(d) & Exp_mask) == Exp_mask)
02701 #else
02702 if (word0(d) == 0x8000)
02703 #endif
02704 {
02705
02706 *decpt = 9999;
02707 #ifdef IEEE_Arith
02708 if (!word1(d) && !(word0(d) & 0xfffff))
02709 {
02710 return nrv_alloc("Inf", rve, 8);
02711 }
02712 #endif
02713 return nrv_alloc("NaN", rve, 3);
02714 }
02715 #endif
02716 #ifdef IBM
02717 dval(d) += 0;
02718 #endif
02719 if (!dval(d))
02720 {
02721 *decpt = 1;
02722 return nrv_alloc("0", rve, 1);
02723 }
02724
02725 #ifdef SET_INEXACT
02726 try_quick = oldinexact = get_inexact();
02727 inexact = 1;
02728 #endif
02729 #ifdef Honor_FLT_ROUNDS
02730 if ((rounding = Flt_Rounds) >= 2)
02731 {
02732 if (*sign)
02733 {
02734 rounding = rounding == 2 ? 0 : 2;
02735 }
02736 else
02737 {
02738 if (rounding != 2)
02739 {
02740 rounding = 0;
02741 }
02742 }
02743 }
02744 #endif
02745
02746 b = d2b(dval(d), &be, &bbits);
02747 #ifdef Sudden_Underflow
02748 i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
02749 #else
02750 if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))))
02751 {
02752 #endif
02753 dval(d2) = dval(d);
02754 word0(d2) &= Frac_mask1;
02755 word0(d2) |= Exp_11;
02756 #ifdef IBM
02757 if (j = 11 - hi0bits(word0(d2) & Frac_mask))
02758 {
02759 dval(d2) /= 1 << j;
02760 }
02761 #endif
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785 i -= Bias;
02786 #ifdef IBM
02787 i <<= 2;
02788 i += j;
02789 #endif
02790 #ifndef Sudden_Underflow
02791 denorm = 0;
02792 }
02793 else
02794 {
02795
02796
02797 i = bbits + be + (Bias + (P-1) - 1);
02798 x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32)
02799 : word1(d) << (32 - i);
02800 dval(d2) = x;
02801 word0(d2) -= 31*Exp_msk1;
02802 i -= (Bias + (P-1) - 1) + 1;
02803 denorm = 1;
02804 }
02805 #endif
02806 ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
02807 k = (int)ds;
02808 if (ds < 0. && ds != k)
02809 {
02810 k--;
02811 }
02812 k_check = 1;
02813 if (k >= 0 && k <= Ten_pmax)
02814 {
02815 if (dval(d) < tens[k])
02816 {
02817 k--;
02818 }
02819 k_check = 0;
02820 }
02821 j = bbits - i - 1;
02822 if (j >= 0)
02823 {
02824 b2 = 0;
02825 s2 = j;
02826 }
02827 else
02828 {
02829 b2 = -j;
02830 s2 = 0;
02831 }
02832 if (k >= 0)
02833 {
02834 b5 = 0;
02835 s5 = k;
02836 s2 += k;
02837 }
02838 else
02839 {
02840 b2 -= k;
02841 b5 = -k;
02842 s5 = 0;
02843 }
02844 if (mode < 0 || mode > 9)
02845 {
02846 mode = 0;
02847 }
02848
02849 #ifndef SET_INEXACT
02850 #ifdef Check_FLT_ROUNDS
02851 try_quick = Rounding == 1;
02852 #else
02853 try_quick = 1;
02854 #endif
02855 #endif
02856
02857 if (mode > 5)
02858 {
02859 mode -= 4;
02860 try_quick = 0;
02861 }
02862 leftright = 1;
02863 switch (mode)
02864 {
02865 case 0:
02866 case 1:
02867 ilim = ilim1 = -1;
02868 i = 18;
02869 ndigits = 0;
02870 break;
02871 case 2:
02872 leftright = 0;
02873
02874 case 4:
02875 if (ndigits <= 0)
02876 {
02877 ndigits = 1;
02878 }
02879 ilim = ilim1 = i = ndigits;
02880 break;
02881 case 3:
02882 leftright = 0;
02883
02884 case 5:
02885 i = ndigits + k + 1;
02886 ilim = i;
02887 ilim1 = i - 1;
02888 if (i <= 0)
02889 {
02890 i = 1;
02891 }
02892 }
02893 s = s0 = rv_alloc(i);
02894
02895 #ifdef Honor_FLT_ROUNDS
02896 if (mode > 1 && rounding != 1)
02897 {
02898 leftright = 0;
02899 }
02900 #endif
02901
02902 if (ilim >= 0 && ilim <= Quick_max && try_quick)
02903 {
02904
02905
02906 i = 0;
02907 dval(d2) = dval(d);
02908 k0 = k;
02909 ilim0 = ilim;
02910 ieps = 2;
02911 if (k > 0)
02912 {
02913 ds = tens[k&0xf];
02914 j = k >> 4;
02915 if (j & Bletch)
02916 {
02917
02918 j &= Bletch - 1;
02919 dval(d) /= bigtens[n_bigtens-1];
02920 ieps++;
02921 }
02922 for (; j; j >>= 1, i++)
02923 {
02924 if (j & 1)
02925 {
02926 ieps++;
02927 ds *= bigtens[i];
02928 }
02929 }
02930 dval(d) /= ds;
02931 }
02932 else if ((j1 = -k))
02933 {
02934 dval(d) *= tens[j1 & 0xf];
02935 for (j = j1 >> 4; j; j >>= 1, i++)
02936 {
02937 if (j & 1)
02938 {
02939 ieps++;
02940 dval(d) *= bigtens[i];
02941 }
02942 }
02943 }
02944 if (k_check && dval(d) < 1. && ilim > 0)
02945 {
02946 if (ilim1 <= 0)
02947 {
02948 goto fast_failed;
02949 }
02950 ilim = ilim1;
02951 k--;
02952 dval(d) *= 10.;
02953 ieps++;
02954 }
02955 dval(eps) = ieps*dval(d) + 7.;
02956 word0(eps) -= (P-1)*Exp_msk1;
02957 if (ilim == 0)
02958 {
02959 S = mhi = 0;
02960 dval(d) -= 5.;
02961 if (dval(d) > dval(eps))
02962 {
02963 goto one_digit;
02964 }
02965 if (dval(d) < -dval(eps))
02966 {
02967 goto no_digits;
02968 }
02969 goto fast_failed;
02970 }
02971 #ifndef No_leftright
02972 if (leftright)
02973 {
02974
02975
02976
02977 dval(eps) = 0.5/tens[ilim-1] - dval(eps);
02978 for (i = 0;;)
02979 {
02980 L = (Long)dval(d);
02981 dval(d) -= L;
02982 *s++ = '0' + (int)L;
02983 if (dval(d) < dval(eps))
02984 {
02985 goto ret1;
02986 }
02987 if (1. - dval(d) < dval(eps))
02988 {
02989 goto bump_up;
02990 }
02991 if (++i >= ilim)
02992 {
02993 break;
02994 }
02995 dval(eps) *= 10.;
02996 dval(d) *= 10.;
02997 }
02998 }
02999 else
03000 {
03001 #endif
03002
03003 dval(eps) *= tens[ilim-1];
03004 for (i = 1;; i++, dval(d) *= 10.)
03005 {
03006 L = (Long)(dval(d));
03007 if (!(dval(d) -= L))
03008 {
03009 ilim = i;
03010 }
03011 *s++ = '0' + (int)L;
03012 if (i == ilim)
03013 {
03014 if (dval(d) > 0.5 + dval(eps))
03015 {
03016 goto bump_up;
03017 }
03018 else if (dval(d) < 0.5 - dval(eps))
03019 {
03020 while (*--s == '0')
03021 {
03022 ;
03023 }
03024 s++;
03025 goto ret1;
03026 }
03027 break;
03028 }
03029 }
03030 #ifndef No_leftright
03031 }
03032 #endif
03033 fast_failed:
03034 s = s0;
03035 dval(d) = dval(d2);
03036 k = k0;
03037 ilim = ilim0;
03038 }
03039
03040
03041
03042 if (be >= 0 && k <= Int_max)
03043 {
03044
03045 ds = tens[k];
03046 if (ndigits < 0 && ilim <= 0)
03047 {
03048 S = mhi = 0;
03049 if (ilim < 0 || dval(d) <= 5*ds)
03050 {
03051 goto no_digits;
03052 }
03053 goto one_digit;
03054 }
03055 for (i = 1; ; i++, dval(d) *= 10.0)
03056 {
03057 L = (Long)(dval(d) / ds);
03058 dval(d) -= L*ds;
03059 #ifdef Check_FLT_ROUNDS
03060
03061 if (dval(d) < 0)
03062 {
03063 L--;
03064 dval(d) += ds;
03065 }
03066 #endif
03067 if (ds <= dval(d))
03068 {
03069 L++;
03070 dval(d) -= ds;
03071 }
03072 *s++ = '0' + (int)L;
03073 if (!dval(d))
03074 {
03075 #ifdef SET_INEXACT
03076 inexact = 0;
03077 #endif
03078 break;
03079 }
03080 if (i == ilim)
03081 {
03082 #ifdef Honor_FLT_ROUNDS
03083 if (mode > 1)
03084 {
03085 switch (rounding)
03086 {
03087 case 0: goto ret1;
03088 case 2: goto bump_up;
03089 }
03090 }
03091 #endif
03092 dval(d) += dval(d);
03093 if (dval(d) > ds || dval(d) == ds && L & 1)
03094 {
03095 bump_up:
03096 while (*--s == '9')
03097 {
03098 if (s == s0)
03099 {
03100 k++;
03101 *s = '0';
03102 break;
03103 }
03104 }
03105 ++*s++;
03106 }
03107 break;
03108 }
03109 }
03110 goto ret1;
03111 }
03112
03113 m2 = b2;
03114 m5 = b5;
03115 mhi = mlo = 0;
03116 if (leftright)
03117 {
03118 i =
03119 #ifndef Sudden_Underflow
03120 denorm ? be + (Bias + (P-1) - 1 + 1) :
03121 #endif
03122 #ifdef IBM
03123 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
03124 #else
03125 1 + P - bbits;
03126 #endif
03127 b2 += i;
03128 s2 += i;
03129 mhi = i2b(1);
03130 }
03131 if (m2 > 0 && s2 > 0)
03132 {
03133 i = m2 < s2 ? m2 : s2;
03134 b2 -= i;
03135 m2 -= i;
03136 s2 -= i;
03137 }
03138 if (b5 > 0)
03139 {
03140 if (leftright)
03141 {
03142 if (m5 > 0)
03143 {
03144 mhi = pow5mult(mhi, m5);
03145 b1 = mult(mhi, b);
03146 Bfree(b);
03147 b = b1;
03148 }
03149 if ((j = b5 - m5))
03150 {
03151 b = pow5mult(b, j);
03152 }
03153 }
03154 else
03155 {
03156 b = pow5mult(b, b5);
03157 }
03158 }
03159 S = i2b(1);
03160 if (s5 > 0)
03161 {
03162 S = pow5mult(S, s5);
03163 }
03164
03165
03166
03167 spec_case = 0;
03168 if ((mode < 2 || leftright)
03169 #ifdef Honor_FLT_ROUNDS
03170 && rounding == 1
03171 #endif
03172 )
03173 {
03174 if (!word1(d) && !(word0(d) & Bndry_mask)
03175 #ifndef Sudden_Underflow
03176 && word0(d) & (Exp_mask & ~Exp_msk1)
03177 #endif
03178 )
03179 {
03180
03181 b2 += Log2P;
03182 s2 += Log2P;
03183 spec_case = 1;
03184 }
03185 }
03186
03187
03188
03189
03190
03191
03192
03193
03194 #ifdef Pack_32
03195 if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f))
03196 {
03197 i = 32 - i;
03198 }
03199 #else
03200 if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf))
03201 {
03202 i = 16 - i;
03203 }
03204 #endif
03205 if (i > 4)
03206 {
03207 i -= 4;
03208 b2 += i;
03209 m2 += i;
03210 s2 += i;
03211 }
03212 else if (i < 4)
03213 {
03214 i += 28;
03215 b2 += i;
03216 m2 += i;
03217 s2 += i;
03218 }
03219 if (b2 > 0)
03220 {
03221 b = lshift(b, b2);
03222 }
03223 if (s2 > 0)
03224 {
03225 S = lshift(S, s2);
03226 }
03227 if (k_check)
03228 {
03229 if (cmp(b,S) < 0)
03230 {
03231 k--;
03232 b = multadd(b, 10, 0);
03233 if (leftright)
03234 {
03235 mhi = multadd(mhi, 10, 0);
03236 }
03237 ilim = ilim1;
03238 }
03239 }
03240 if (ilim <= 0 && (mode == 3 || mode == 5))
03241 {
03242 if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0)
03243 {
03244
03245 no_digits:
03246 k = -1 - ndigits;
03247 goto ret;
03248 }
03249 one_digit:
03250 *s++ = '1';
03251 k++;
03252 goto ret;
03253 }
03254 if (leftright)
03255 {
03256 if (m2 > 0)
03257 {
03258 mhi = lshift(mhi, m2);
03259 }
03260
03261
03262
03263
03264
03265 mlo = mhi;
03266 if (spec_case)
03267 {
03268 mhi = Balloc(mhi->k);
03269 Bcopy(mhi, mlo);
03270 mhi = lshift(mhi, Log2P);
03271 }
03272
03273 for (i = 1;;i++)
03274 {
03275 dig = quorem(b,S) + '0';
03276
03277
03278
03279 j = cmp(b, mlo);
03280 delta = diff(S, mhi);
03281 j1 = delta->sign ? 1 : cmp(b, delta);
03282 Bfree(delta);
03283 #ifndef ROUND_BIASED
03284 if (j1 == 0 && mode != 1 && !(word1(d) & 1)
03285 #ifdef Honor_FLT_ROUNDS
03286 && rounding >= 1
03287 #endif
03288 )
03289 {
03290 if (dig == '9')
03291 {
03292 goto round_9_up;
03293 }
03294 if (j > 0)
03295 {
03296 dig++;
03297 }
03298 #ifdef SET_INEXACT
03299 else if (!b->x[0] && b->wds <= 1)
03300 {
03301 inexact = 0;
03302 }
03303 #endif
03304 *s++ = dig;
03305 goto ret;
03306 }
03307 #endif
03308 if (j < 0 || j == 0 && mode != 1
03309 #ifndef ROUND_BIASED
03310 && !(word1(d) & 1)
03311 #endif
03312 )
03313 {
03314 if (!b->x[0] && b->wds <= 1)
03315 {
03316 #ifdef SET_INEXACT
03317 inexact = 0;
03318 #endif
03319 goto accept_dig;
03320 }
03321 #ifdef Honor_FLT_ROUNDS
03322 if (mode > 1)
03323 {
03324 switch (rounding)
03325 {
03326 case 0: goto accept_dig;
03327 case 2: goto keep_dig;
03328 }
03329 }
03330 #endif
03331 if (j1 > 0)
03332 {
03333 b = lshift(b, 1);
03334 j1 = cmp(b, S);
03335 if ( (j1 > 0 || j1 == 0 && dig & 1)
03336 && dig++ == '9')
03337 {
03338 goto round_9_up;
03339 }
03340 }
03341 accept_dig:
03342 *s++ = dig;
03343 goto ret;
03344 }
03345 if (j1 > 0)
03346 {
03347 #ifdef Honor_FLT_ROUNDS
03348 if (!rounding)
03349 {
03350 goto accept_dig;
03351 }
03352 #endif
03353 if (dig == '9')
03354 {
03355
03356 round_9_up:
03357 *s++ = '9';
03358 goto roundoff;
03359 }
03360 *s++ = dig + 1;
03361 goto ret;
03362 }
03363 #ifdef Honor_FLT_ROUNDS
03364 keep_dig:
03365 #endif
03366 *s++ = dig;
03367 if (i == ilim)
03368 {
03369 break;
03370 }
03371 b = multadd(b, 10, 0);
03372 if (mlo == mhi)
03373 {
03374 mlo = mhi = multadd(mhi, 10, 0);
03375 }
03376 else
03377 {
03378 mlo = multadd(mlo, 10, 0);
03379 mhi = multadd(mhi, 10, 0);
03380 }
03381 }
03382 }
03383 else
03384 {
03385 for (i = 1;; i++)
03386 {
03387 *s++ = dig = quorem(b,S) + '0';
03388 if (!b->x[0] && b->wds <= 1)
03389 {
03390 #ifdef SET_INEXACT
03391 inexact = 0;
03392 #endif
03393 goto ret;
03394 }
03395 if (i >= ilim)
03396 {
03397 break;
03398 }
03399 b = multadd(b, 10, 0);
03400 }
03401 }
03402
03403
03404
03405 #ifdef Honor_FLT_ROUNDS
03406 switch (rounding)
03407 {
03408 case 0: goto trimzeros;
03409 case 2: goto roundoff;
03410 }
03411 #endif
03412 b = lshift(b, 1);
03413 j = cmp(b, S);
03414 if (j > 0 || j == 0 && dig & 1)
03415 {
03416 roundoff:
03417 while (*--s == '9')
03418 {
03419 if (s == s0)
03420 {
03421 k++;
03422 *s++ = '1';
03423 goto ret;
03424 }
03425 }
03426 ++*s++;
03427 }
03428 else
03429 {
03430 #ifdef Honor_FLT_ROUNDS
03431 trimzeros:
03432 #endif
03433 while (*--s == '0')
03434 {
03435 ;
03436 }
03437 s++;
03438 }
03439 ret:
03440 Bfree(S);
03441 if (mhi)
03442 {
03443 if (mlo && mlo != mhi)
03444 {
03445 Bfree(mlo);
03446 }
03447 Bfree(mhi);
03448 }
03449 ret1:
03450 #ifdef SET_INEXACT
03451 if (inexact)
03452 {
03453 if (!oldinexact)
03454 {
03455 word0(d) = Exp_1 + (70 << Exp_shift);
03456 word1(d) = 0;
03457 dval(d) += 1.;
03458 }
03459 }
03460 else if (!oldinexact)
03461 {
03462 clear_inexact();
03463 }
03464 #endif
03465 Bfree(b);
03466 *s = 0;
03467 *decpt = k + 1;
03468 if (rve)
03469 {
03470 *rve = s;
03471 }
03472 return s0;
03473 }
03474
03475 #if defined(HAVE_FPU_CONTROL_H) \
03476 && defined(_FPU_GETCW) \
03477 && defined(_FPU_SETCW)
03478
03479 fpu_control_t maskoff = 0
03480 #if defined(_FPU_EXTENDED)
03481 | _FPU_EXTENDED
03482 #endif
03483 #if defined(_FPU_SINGLE)
03484 | _FPU_SINGLE
03485 #endif
03486 ;
03487
03488 fpu_control_t maskon = 0
03489 #if defined(_FPU_DOUBLE)
03490 | _FPU_DOUBLE
03491 #endif
03492 ;
03493
03494 fpu_control_t origcw;
03495
03496 void mux_FPInit(void)
03497 {
03498 _FPU_GETCW(origcw);
03499 }
03500
03501 void mux_FPSet(void)
03502 {
03503
03504
03505 fpu_control_t newcw;
03506 newcw = (origcw & ~maskoff) | maskon;
03507 _FPU_SETCW(newcw);
03508 }
03509
03510 void mux_FPRestore(void)
03511 {
03512 _FPU_SETCW(origcw);
03513 }
03514
03515 #elif defined(IEEEFP_H_USEABLE)
03516
03517 fp_rnd_t orig_rnd;
03518 fp_prec_t orig_prec;
03519
03520 void mux_FPInit(void)
03521 {
03522 orig_rnd = fpgetround();
03523 orig_prec = fpgetprec();
03524 }
03525
03526 void mux_FPSet(void)
03527 {
03528
03529
03530 fpsetprec(FP_PD);
03531 }
03532
03533 void mux_FPRestore(void)
03534 {
03535 fpsetprec(orig_prec);
03536 }
03537
03538 #elif defined(WIN32)
03539
03540 static unsigned origcw;
03541
03542 void mux_FPInit(void)
03543 {
03544 origcw = _controlfp(0, 0);
03545 }
03546
03547 void mux_FPSet(void)
03548 {
03549
03550
03551 _controlfp(_PC_53, _MCW_PC);
03552 }
03553
03554 void mux_FPRestore(void)
03555 {
03556 const unsigned int maskall = 0xFFFFFFFF;
03557
03558 _controlfp(origcw, maskall);
03559 }
03560
03561 #elif defined(HAVE_FENV_H) \
03562 && defined(HAVE_FESETPREC) \
03563 && defined(HAVE_FEGETPREC) \
03564 && defined(FE_DBLPREC)
03565
03566 int origcw;
03567
03568 void mux_FPInit(void)
03569 {
03570 origcw = fegetprec();
03571 }
03572
03573 void mux_FPSet(void)
03574 {
03575
03576
03577 fesetprec(FE_DBLPREC);
03578 }
03579
03580 void mux_FPRestore(void)
03581 {
03582 fesetprec(origcw);
03583 }
03584
03585 #else
03586
03587 #warning "No method of floating-point control was found, using dummy functions"
03588
03589 void mux_FPInit(void)
03590 {
03591 }
03592
03593 void mux_FPSet(void)
03594 {
03595 }
03596
03597 void mux_FPRestore(void)
03598 {
03599 }
03600
03601 #endif
03602
03603 void FLOAT_Initialize(void)
03604 {
03605 mux_FPInit();
03606 mux_FPSet();
03607 }