1 /**************************************************************** 2 3 The author of this software is David M. Gay. 4 5 Copyright (C) 1998, 1999 by Lucent Technologies 6 All Rights Reserved 7 8 Permission to use, copy, modify, and distribute this software and 9 its documentation for any purpose and without fee is hereby 10 granted, provided that the above copyright notice appear in all 11 copies and that both that the copyright notice and this 12 permission notice and warranty disclaimer appear in supporting 13 documentation, and that the name of Lucent or any of its entities 14 not be used in advertising or publicity pertaining to 15 distribution of the software without specific, written prior 16 permission. 17 18 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 19 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. 20 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY 21 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 22 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 23 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 24 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF 25 THIS SOFTWARE. 26 27 ****************************************************************/ 28 29 /* Please send bug reports to David M. Gay (dmg at acm dot org, 30 * with " at " changed at "@" and " dot " changed to "."). */ 31 32 #include "gdtoaimp.h" 33 34 static Bigint *freelist[Kmax+1]; 35 #ifndef Omit_Private_Memory 36 #ifndef PRIVATE_MEM 37 #define PRIVATE_MEM 2304 38 #endif 39 #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) 40 static double private_mem[PRIVATE_mem], *pmem_next = private_mem; 41 #endif 42 43 #ifdef MULTIPLE_THREADS 44 static void *__dtoa_locks[] = { NULL, NULL }; 45 #endif 46 47 Bigint * 48 Balloc 49 #ifdef KR_headers 50 (k) int k; 51 #else 52 (int k) 53 #endif 54 { 55 int x; 56 Bigint *rv; 57 #ifndef Omit_Private_Memory 58 unsigned int len; 59 #endif 60 61 ACQUIRE_DTOA_LOCK(0); 62 /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ 63 /* but this case seems very unlikely. */ 64 if (k <= Kmax && (rv = freelist[k]) !=0) { 65 freelist[k] = rv->next; 66 } 67 else { 68 x = 1 << k; 69 #ifdef Omit_Private_Memory 70 rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); 71 if (rv == NULL) 72 return (NULL); 73 #else 74 len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) 75 /sizeof(double); 76 if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { 77 rv = (Bigint*)pmem_next; 78 pmem_next += len; 79 } 80 else { 81 rv = (Bigint*)MALLOC(len*sizeof(double)); 82 if (rv == NULL) 83 return (NULL); 84 } 85 #endif 86 rv->k = k; 87 rv->maxwds = x; 88 } 89 FREE_DTOA_LOCK(0); 90 rv->sign = rv->wds = 0; 91 return rv; 92 } 93 94 void 95 Bfree 96 #ifdef KR_headers 97 (v) Bigint *v; 98 #else 99 (Bigint *v) 100 #endif 101 { 102 if (v) { 103 if (v->k > Kmax) 104 #ifdef FREE 105 FREE(v); 106 #else 107 free(v); 108 #endif 109 else { 110 ACQUIRE_DTOA_LOCK(0); 111 v->next = freelist[v->k]; 112 freelist[v->k] = v; 113 FREE_DTOA_LOCK(0); 114 } 115 } 116 } 117 118 int 119 lo0bits 120 #ifdef KR_headers 121 (y) ULong *y; 122 #else 123 (ULong *y) 124 #endif 125 { 126 int k; 127 ULong x = *y; 128 129 if (x & 7) { 130 if (x & 1) 131 return 0; 132 if (x & 2) { 133 *y = x >> 1; 134 return 1; 135 } 136 *y = x >> 2; 137 return 2; 138 } 139 k = 0; 140 if (!(x & 0xffff)) { 141 k = 16; 142 x >>= 16; 143 } 144 if (!(x & 0xff)) { 145 k += 8; 146 x >>= 8; 147 } 148 if (!(x & 0xf)) { 149 k += 4; 150 x >>= 4; 151 } 152 if (!(x & 0x3)) { 153 k += 2; 154 x >>= 2; 155 } 156 if (!(x & 1)) { 157 k++; 158 x >>= 1; 159 if (!x) 160 return 32; 161 } 162 *y = x; 163 return k; 164 } 165 166 Bigint * 167 multadd 168 #ifdef KR_headers 169 (b, m, a) Bigint *b; int m, a; 170 #else 171 (Bigint *b, int m, int a) /* multiply by m and add a */ 172 #endif 173 { 174 int i, wds; 175 #ifdef ULLong 176 ULong *x; 177 ULLong carry, y; 178 #else 179 ULong carry, *x, y; 180 #ifdef Pack_32 181 ULong xi, z; 182 #endif 183 #endif 184 Bigint *b1; 185 186 wds = b->wds; 187 x = b->x; 188 i = 0; 189 carry = a; 190 do { 191 #ifdef ULLong 192 y = *x * (ULLong)m + carry; 193 carry = y >> 32; 194 *x++ = y & 0xffffffffUL; 195 #else 196 #ifdef Pack_32 197 xi = *x; 198 y = (xi & 0xffff) * m + carry; 199 z = (xi >> 16) * m + (y >> 16); 200 carry = z >> 16; 201 *x++ = (z << 16) + (y & 0xffff); 202 #else 203 y = *x * m + carry; 204 carry = y >> 16; 205 *x++ = y & 0xffff; 206 #endif 207 #endif 208 } 209 while(++i < wds); 210 if (carry) { 211 if (wds >= b->maxwds) { 212 b1 = Balloc(b->k+1); 213 if (b1 == NULL) 214 return (NULL); 215 Bcopy(b1, b); 216 Bfree(b); 217 b = b1; 218 } 219 b->x[wds++] = carry; 220 b->wds = wds; 221 } 222 return b; 223 } 224 225 int 226 hi0bits_D2A 227 #ifdef KR_headers 228 (x) ULong x; 229 #else 230 (ULong x) 231 #endif 232 { 233 int k = 0; 234 235 if (!(x & 0xffff0000)) { 236 k = 16; 237 x <<= 16; 238 } 239 if (!(x & 0xff000000)) { 240 k += 8; 241 x <<= 8; 242 } 243 if (!(x & 0xf0000000)) { 244 k += 4; 245 x <<= 4; 246 } 247 if (!(x & 0xc0000000)) { 248 k += 2; 249 x <<= 2; 250 } 251 if (!(x & 0x80000000)) { 252 k++; 253 if (!(x & 0x40000000)) 254 return 32; 255 } 256 return k; 257 } 258 259 Bigint * 260 i2b 261 #ifdef KR_headers 262 (i) int i; 263 #else 264 (int i) 265 #endif 266 { 267 Bigint *b; 268 269 b = Balloc(1); 270 if (b == NULL) 271 return (NULL); 272 b->x[0] = i; 273 b->wds = 1; 274 return b; 275 } 276 277 Bigint * 278 mult 279 #ifdef KR_headers 280 (a, b) Bigint *a, *b; 281 #else 282 (Bigint *a, Bigint *b) 283 #endif 284 { 285 Bigint *c; 286 int k, wa, wb, wc; 287 ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; 288 ULong y; 289 #ifdef ULLong 290 ULLong carry, z; 291 #else 292 ULong carry, z; 293 #ifdef Pack_32 294 ULong z2; 295 #endif 296 #endif 297 298 if (a->wds < b->wds) { 299 c = a; 300 a = b; 301 b = c; 302 } 303 k = a->k; 304 wa = a->wds; 305 wb = b->wds; 306 wc = wa + wb; 307 if (wc > a->maxwds) 308 k++; 309 c = Balloc(k); 310 if (c == NULL) 311 return (NULL); 312 for(x = c->x, xa = x + wc; x < xa; x++) 313 *x = 0; 314 xa = a->x; 315 xae = xa + wa; 316 xb = b->x; 317 xbe = xb + wb; 318 xc0 = c->x; 319 #ifdef ULLong 320 for(; xb < xbe; xc0++) { 321 if ( (y = *xb++) !=0) { 322 x = xa; 323 xc = xc0; 324 carry = 0; 325 do { 326 z = *x++ * (ULLong)y + *xc + carry; 327 carry = z >> 32; 328 *xc++ = z & 0xffffffffUL; 329 } 330 while(x < xae); 331 *xc = carry; 332 } 333 } 334 #else 335 #ifdef Pack_32 336 for(; xb < xbe; xb++, xc0++) { 337 if ( (y = *xb & 0xffff) !=0) { 338 x = xa; 339 xc = xc0; 340 carry = 0; 341 do { 342 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; 343 carry = z >> 16; 344 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; 345 carry = z2 >> 16; 346 Storeinc(xc, z2, z); 347 } 348 while(x < xae); 349 *xc = carry; 350 } 351 if ( (y = *xb >> 16) !=0) { 352 x = xa; 353 xc = xc0; 354 carry = 0; 355 z2 = *xc; 356 do { 357 z = (*x & 0xffff) * y + (*xc >> 16) + carry; 358 carry = z >> 16; 359 Storeinc(xc, z, z2); 360 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; 361 carry = z2 >> 16; 362 } 363 while(x < xae); 364 *xc = z2; 365 } 366 } 367 #else 368 for(; xb < xbe; xc0++) { 369 if ( (y = *xb++) !=0) { 370 x = xa; 371 xc = xc0; 372 carry = 0; 373 do { 374 z = *x++ * y + *xc + carry; 375 carry = z >> 16; 376 *xc++ = z & 0xffff; 377 } 378 while(x < xae); 379 *xc = carry; 380 } 381 } 382 #endif 383 #endif 384 for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; 385 c->wds = wc; 386 return c; 387 } 388 389 static Bigint *p5s; 390 391 Bigint * 392 pow5mult 393 #ifdef KR_headers 394 (b, k) Bigint *b; int k; 395 #else 396 (Bigint *b, int k) 397 #endif 398 { 399 Bigint *b1, *p5, *p51; 400 int i; 401 static int p05[3] = { 5, 25, 125 }; 402 403 if ( (i = k & 3) !=0) { 404 b = multadd(b, p05[i-1], 0); 405 if (b == NULL) 406 return (NULL); 407 } 408 409 if (!(k >>= 2)) 410 return b; 411 if ((p5 = p5s) == 0) { 412 /* first time */ 413 #ifdef MULTIPLE_THREADS 414 ACQUIRE_DTOA_LOCK(1); 415 if (!(p5 = p5s)) { 416 p5 = p5s = i2b(625); 417 if (p5 == NULL) 418 return (NULL); 419 p5->next = 0; 420 } 421 FREE_DTOA_LOCK(1); 422 #else 423 p5 = p5s = i2b(625); 424 if (p5 == NULL) 425 return (NULL); 426 p5->next = 0; 427 #endif 428 } 429 for(;;) { 430 if (k & 1) { 431 b1 = mult(b, p5); 432 if (b1 == NULL) 433 return (NULL); 434 Bfree(b); 435 b = b1; 436 } 437 if (!(k >>= 1)) 438 break; 439 if ((p51 = p5->next) == 0) { 440 #ifdef MULTIPLE_THREADS 441 ACQUIRE_DTOA_LOCK(1); 442 if (!(p51 = p5->next)) { 443 p51 = p5->next = mult(p5,p5); 444 if (p51 == NULL) 445 return (NULL); 446 p51->next = 0; 447 } 448 FREE_DTOA_LOCK(1); 449 #else 450 p51 = p5->next = mult(p5,p5); 451 if (p51 == NULL) 452 return (NULL); 453 p51->next = 0; 454 #endif 455 } 456 p5 = p51; 457 } 458 return b; 459 } 460 461 Bigint * 462 lshift 463 #ifdef KR_headers 464 (b, k) Bigint *b; int k; 465 #else 466 (Bigint *b, int k) 467 #endif 468 { 469 int i, k1, n, n1; 470 Bigint *b1; 471 ULong *x, *x1, *xe, z; 472 473 n = k >> kshift; 474 k1 = b->k; 475 n1 = n + b->wds + 1; 476 for(i = b->maxwds; n1 > i; i <<= 1) 477 k1++; 478 b1 = Balloc(k1); 479 if (b1 == NULL) 480 return (NULL); 481 x1 = b1->x; 482 for(i = 0; i < n; i++) 483 *x1++ = 0; 484 x = b->x; 485 xe = x + b->wds; 486 if (k &= kmask) { 487 #ifdef Pack_32 488 k1 = 32 - k; 489 z = 0; 490 do { 491 *x1++ = *x << k | z; 492 z = *x++ >> k1; 493 } 494 while(x < xe); 495 if ((*x1 = z) !=0) 496 ++n1; 497 #else 498 k1 = 16 - k; 499 z = 0; 500 do { 501 *x1++ = *x << k & 0xffff | z; 502 z = *x++ >> k1; 503 } 504 while(x < xe); 505 if (*x1 = z) 506 ++n1; 507 #endif 508 } 509 else do 510 *x1++ = *x++; 511 while(x < xe); 512 b1->wds = n1 - 1; 513 Bfree(b); 514 return b1; 515 } 516 517 int 518 cmp 519 #ifdef KR_headers 520 (a, b) Bigint *a, *b; 521 #else 522 (Bigint *a, Bigint *b) 523 #endif 524 { 525 ULong *xa, *xa0, *xb, *xb0; 526 int i, j; 527 528 i = a->wds; 529 j = b->wds; 530 #ifdef DEBUG 531 if (i > 1 && !a->x[i-1]) 532 Bug("cmp called with a->x[a->wds-1] == 0"); 533 if (j > 1 && !b->x[j-1]) 534 Bug("cmp called with b->x[b->wds-1] == 0"); 535 #endif 536 if (i -= j) 537 return i; 538 xa0 = a->x; 539 xa = xa0 + j; 540 xb0 = b->x; 541 xb = xb0 + j; 542 for(;;) { 543 if (*--xa != *--xb) 544 return *xa < *xb ? -1 : 1; 545 if (xa <= xa0) 546 break; 547 } 548 return 0; 549 } 550 551 Bigint * 552 diff 553 #ifdef KR_headers 554 (a, b) Bigint *a, *b; 555 #else 556 (Bigint *a, Bigint *b) 557 #endif 558 { 559 Bigint *c; 560 int i, wa, wb; 561 ULong *xa, *xae, *xb, *xbe, *xc; 562 #ifdef ULLong 563 ULLong borrow, y; 564 #else 565 ULong borrow, y; 566 #ifdef Pack_32 567 ULong z; 568 #endif 569 #endif 570 571 i = cmp(a,b); 572 if (!i) { 573 c = Balloc(0); 574 if (c == NULL) 575 return (NULL); 576 c->wds = 1; 577 c->x[0] = 0; 578 return c; 579 } 580 if (i < 0) { 581 c = a; 582 a = b; 583 b = c; 584 i = 1; 585 } 586 else 587 i = 0; 588 c = Balloc(a->k); 589 if (c == NULL) 590 return (NULL); 591 c->sign = i; 592 wa = a->wds; 593 xa = a->x; 594 xae = xa + wa; 595 wb = b->wds; 596 xb = b->x; 597 xbe = xb + wb; 598 xc = c->x; 599 borrow = 0; 600 #ifdef ULLong 601 do { 602 y = (ULLong)*xa++ - *xb++ - borrow; 603 borrow = y >> 32 & 1UL; 604 *xc++ = y & 0xffffffffUL; 605 } 606 while(xb < xbe); 607 while(xa < xae) { 608 y = *xa++ - borrow; 609 borrow = y >> 32 & 1UL; 610 *xc++ = y & 0xffffffffUL; 611 } 612 #else 613 #ifdef Pack_32 614 do { 615 y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; 616 borrow = (y & 0x10000) >> 16; 617 z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; 618 borrow = (z & 0x10000) >> 16; 619 Storeinc(xc, z, y); 620 } 621 while(xb < xbe); 622 while(xa < xae) { 623 y = (*xa & 0xffff) - borrow; 624 borrow = (y & 0x10000) >> 16; 625 z = (*xa++ >> 16) - borrow; 626 borrow = (z & 0x10000) >> 16; 627 Storeinc(xc, z, y); 628 } 629 #else 630 do { 631 y = *xa++ - *xb++ - borrow; 632 borrow = (y & 0x10000) >> 16; 633 *xc++ = y & 0xffff; 634 } 635 while(xb < xbe); 636 while(xa < xae) { 637 y = *xa++ - borrow; 638 borrow = (y & 0x10000) >> 16; 639 *xc++ = y & 0xffff; 640 } 641 #endif 642 #endif 643 while(!*--xc) 644 wa--; 645 c->wds = wa; 646 return c; 647 } 648 649 double 650 b2d 651 #ifdef KR_headers 652 (a, e) Bigint *a; int *e; 653 #else 654 (Bigint *a, int *e) 655 #endif 656 { 657 ULong *xa, *xa0, w, y, z; 658 int k; 659 U d; 660 #ifdef VAX 661 ULong d0, d1; 662 #else 663 #define d0 word0(&d) 664 #define d1 word1(&d) 665 #endif 666 667 xa0 = a->x; 668 xa = xa0 + a->wds; 669 y = *--xa; 670 #ifdef DEBUG 671 if (!y) Bug("zero y in b2d"); 672 #endif 673 k = hi0bits(y); 674 *e = 32 - k; 675 #ifdef Pack_32 676 if (k < Ebits) { 677 d0 = Exp_1 | y >> (Ebits - k); 678 w = xa > xa0 ? *--xa : 0; 679 d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); 680 goto ret_d; 681 } 682 z = xa > xa0 ? *--xa : 0; 683 if (k -= Ebits) { 684 d0 = Exp_1 | y << k | z >> (32 - k); 685 y = xa > xa0 ? *--xa : 0; 686 d1 = z << k | y >> (32 - k); 687 } 688 else { 689 d0 = Exp_1 | y; 690 d1 = z; 691 } 692 #else 693 if (k < Ebits + 16) { 694 z = xa > xa0 ? *--xa : 0; 695 d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; 696 w = xa > xa0 ? *--xa : 0; 697 y = xa > xa0 ? *--xa : 0; 698 d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; 699 goto ret_d; 700 } 701 z = xa > xa0 ? *--xa : 0; 702 w = xa > xa0 ? *--xa : 0; 703 k -= Ebits + 16; 704 d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; 705 y = xa > xa0 ? *--xa : 0; 706 d1 = w << k + 16 | y << k; 707 #endif 708 ret_d: 709 #ifdef VAX 710 word0(&d) = d0 >> 16 | d0 << 16; 711 word1(&d) = d1 >> 16 | d1 << 16; 712 #endif 713 return dval(&d); 714 } 715 #undef d0 716 #undef d1 717 718 Bigint * 719 d2b 720 #ifdef KR_headers 721 (dd, e, bits) double dd; int *e, *bits; 722 #else 723 (double dd, int *e, int *bits) 724 #endif 725 { 726 Bigint *b; 727 U d; 728 #ifndef Sudden_Underflow 729 int i; 730 #endif 731 int de, k; 732 ULong *x, y, z; 733 #ifdef VAX 734 ULong d0, d1; 735 #else 736 #define d0 word0(&d) 737 #define d1 word1(&d) 738 #endif 739 d.d = dd; 740 #ifdef VAX 741 d0 = word0(&d) >> 16 | word0(&d) << 16; 742 d1 = word1(&d) >> 16 | word1(&d) << 16; 743 #endif 744 745 #ifdef Pack_32 746 b = Balloc(1); 747 #else 748 b = Balloc(2); 749 #endif 750 if (b == NULL) 751 return (NULL); 752 x = b->x; 753 754 z = d0 & Frac_mask; 755 d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ 756 #ifdef Sudden_Underflow 757 de = (int)(d0 >> Exp_shift); 758 #ifndef IBM 759 z |= Exp_msk11; 760 #endif 761 #else 762 if ( (de = (int)(d0 >> Exp_shift)) !=0) 763 z |= Exp_msk1; 764 #endif 765 #ifdef Pack_32 766 if ( (y = d1) !=0) { 767 if ( (k = lo0bits(&y)) !=0) { 768 x[0] = y | z << (32 - k); 769 z >>= k; 770 } 771 else 772 x[0] = y; 773 #ifndef Sudden_Underflow 774 i = 775 #endif 776 b->wds = (x[1] = z) !=0 ? 2 : 1; 777 } 778 else { 779 k = lo0bits(&z); 780 x[0] = z; 781 #ifndef Sudden_Underflow 782 i = 783 #endif 784 b->wds = 1; 785 k += 32; 786 } 787 #else 788 if ( (y = d1) !=0) { 789 if ( (k = lo0bits(&y)) !=0) 790 if (k >= 16) { 791 x[0] = y | z << 32 - k & 0xffff; 792 x[1] = z >> k - 16 & 0xffff; 793 x[2] = z >> k; 794 i = 2; 795 } 796 else { 797 x[0] = y & 0xffff; 798 x[1] = y >> 16 | z << 16 - k & 0xffff; 799 x[2] = z >> k & 0xffff; 800 x[3] = z >> k+16; 801 i = 3; 802 } 803 else { 804 x[0] = y & 0xffff; 805 x[1] = y >> 16; 806 x[2] = z & 0xffff; 807 x[3] = z >> 16; 808 i = 3; 809 } 810 } 811 else { 812 #ifdef DEBUG 813 if (!z) 814 Bug("Zero passed to d2b"); 815 #endif 816 k = lo0bits(&z); 817 if (k >= 16) { 818 x[0] = z; 819 i = 0; 820 } 821 else { 822 x[0] = z & 0xffff; 823 x[1] = z >> 16; 824 i = 1; 825 } 826 k += 32; 827 } 828 while(!x[i]) 829 --i; 830 b->wds = i + 1; 831 #endif 832 #ifndef Sudden_Underflow 833 if (de) { 834 #endif 835 #ifdef IBM 836 *e = (de - Bias - (P-1) << 2) + k; 837 *bits = 4*P + 8 - k - hi0bits(word0(&d) & Frac_mask); 838 #else 839 *e = de - Bias - (P-1) + k; 840 *bits = P - k; 841 #endif 842 #ifndef Sudden_Underflow 843 } 844 else { 845 *e = de - Bias - (P-1) + 1 + k; 846 #ifdef Pack_32 847 *bits = 32*i - hi0bits(x[i-1]); 848 #else 849 *bits = (i+2)*16 - hi0bits(x[i]); 850 #endif 851 } 852 #endif 853 return b; 854 } 855 #undef d0 856 #undef d1 857 858 CONST double 859 #ifdef IEEE_Arith 860 bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; 861 CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 862 }; 863 #else 864 #ifdef IBM 865 bigtens[] = { 1e16, 1e32, 1e64 }; 866 CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 }; 867 #else 868 bigtens[] = { 1e16, 1e32 }; 869 CONST double tinytens[] = { 1e-16, 1e-32 }; 870 #endif 871 #endif 872 873 CONST double 874 tens[] = { 875 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 876 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 877 1e20, 1e21, 1e22 878 #ifdef VAX 879 , 1e23, 1e24 880 #endif 881 }; 882 883 #ifdef NO_STRING_H 884 885 char * 886 #ifdef KR_headers 887 strcp_D2A(a, b) char *a; char *b; 888 #else 889 strcp_D2A(char *a, CONST char *b) 890 #endif 891 { 892 while((*a = *b++)) 893 a++; 894 return a; 895 } 896 897 Char * 898 #ifdef KR_headers 899 memcpy_D2A(a, b, len) Char *a; Char *b; size_t len; 900 #else 901 memcpy_D2A(void *a1, void *b1, size_t len) 902 #endif 903 { 904 char *a = (char*)a1, *ae = a + len; 905 char *b = (char*)b1, *a0 = a; 906 while(a < ae) 907 *a++ = *b++; 908 return a0; 909 } 910 911 #endif /* NO_STRING_H */ 912