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