strtod.c revision 112415
1/****************************************************************
2
3The author of this software is David M. Gay.
4
5Copyright (C) 1998-2001 by Lucent Technologies
6All Rights Reserved
7
8Permission to use, copy, modify, and distribute this software and
9its documentation for any purpose and without fee is hereby
10granted, provided that the above copyright notice appear in all
11copies and that both that the copyright notice and this
12permission notice and warranty disclaimer appear in supporting
13documentation, and that the name of Lucent or any of its entities
14not be used in advertising or publicity pertaining to
15distribution of the software without specific, written prior
16permission.
17
18LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25THIS SOFTWARE.
26
27****************************************************************/
28
29/* Please send bug reports to
30	David M. Gay
31	Bell Laboratories, Room 2C-463
32	600 Mountain Avenue
33	Murray Hill, NJ 07974-0636
34	U.S.A.
35	dmg@bell-labs.com
36 */
37
38#include "gdtoaimp.h"
39
40#ifdef USE_LOCALE
41#include "locale.h"
42#endif
43
44#ifdef IEEE_Arith
45#ifndef NO_IEEE_Scale
46#define Avoid_Underflow
47#undef tinytens
48/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
49/* flag unnecessarily.  It leads to a song and dance at the end of strtod. */
50static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
51		9007199254740992.e-256
52		};
53#endif
54#endif
55
56#ifdef Honor_FLT_ROUNDS
57#define Rounding rounding
58#undef Check_FLT_ROUNDS
59#define Check_FLT_ROUNDS
60#else
61#define Rounding Flt_Rounds
62#endif
63
64 double
65strtod
66#ifdef KR_headers
67	(s00, se) CONST char *s00; char **se;
68#else
69	(CONST char *s00, char **se)
70#endif
71{
72#ifdef Avoid_Underflow
73	int scale;
74#endif
75	int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
76		 e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
77	CONST char *s, *s0, *s1;
78	double aadj, aadj1, adj, rv, rv0;
79	Long L;
80	ULong y, z;
81	Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
82#ifdef SET_INEXACT
83	int inexact, oldinexact;
84#endif
85#ifdef Honor_FLT_ROUNDS
86	int rounding;
87#endif
88
89	sign = nz0 = nz = 0;
90	dval(rv) = 0.;
91	for(s = s00;;s++) switch(*s) {
92		case '-':
93			sign = 1;
94			/* no break */
95		case '+':
96			if (*++s)
97				goto break2;
98			/* no break */
99		case 0:
100			goto ret0;
101		case '\t':
102		case '\n':
103		case '\v':
104		case '\f':
105		case '\r':
106		case ' ':
107			continue;
108		default:
109			goto break2;
110		}
111 break2:
112	if (*s == '0') {
113#ifndef NO_HEX_FP
114		{
115		static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
116		Long exp;
117		ULong bits[2];
118		switch(s[1]) {
119		  case 'x':
120		  case 'X':
121			switch(gethex(&s, &fpi, &exp, &bb, sign)) {
122			  case STRTOG_NoNumber:
123				s = s00;
124				sign = 0;
125			  case STRTOG_Zero:
126				break;
127			  default:
128				copybits(bits, fpi.nbits, bb);
129				Bfree(bb);
130				ULtod(((U*)&rv)->L, bits, exp, i);
131			  }
132			goto ret;
133		  }
134		}
135#endif
136		nz0 = 1;
137		while(*++s == '0') ;
138		if (!*s)
139			goto ret;
140		}
141	s0 = s;
142	y = z = 0;
143	for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
144		if (nd < 9)
145			y = 10*y + c - '0';
146		else if (nd < 16)
147			z = 10*z + c - '0';
148	nd0 = nd;
149#ifdef USE_LOCALE
150	if (c == *localeconv()->decimal_point)
151#else
152	if (c == '.')
153#endif
154		{
155		c = *++s;
156		if (!nd) {
157			for(; c == '0'; c = *++s)
158				nz++;
159			if (c > '0' && c <= '9') {
160				s0 = s;
161				nf += nz;
162				nz = 0;
163				goto have_dig;
164				}
165			goto dig_done;
166			}
167		for(; c >= '0' && c <= '9'; c = *++s) {
168 have_dig:
169			nz++;
170			if (c -= '0') {
171				nf += nz;
172				for(i = 1; i < nz; i++)
173					if (nd++ < 9)
174						y *= 10;
175					else if (nd <= DBL_DIG + 1)
176						z *= 10;
177				if (nd++ < 9)
178					y = 10*y + c;
179				else if (nd <= DBL_DIG + 1)
180					z = 10*z + c;
181				nz = 0;
182				}
183			}
184		}
185 dig_done:
186	e = 0;
187	if (c == 'e' || c == 'E') {
188		if (!nd && !nz && !nz0) {
189			goto ret0;
190			}
191		s00 = s;
192		esign = 0;
193		switch(c = *++s) {
194			case '-':
195				esign = 1;
196			case '+':
197				c = *++s;
198			}
199		if (c >= '0' && c <= '9') {
200			while(c == '0')
201				c = *++s;
202			if (c > '0' && c <= '9') {
203				L = c - '0';
204				s1 = s;
205				while((c = *++s) >= '0' && c <= '9')
206					L = 10*L + c - '0';
207				if (s - s1 > 8 || L > 19999)
208					/* Avoid confusion from exponents
209					 * so large that e might overflow.
210					 */
211					e = 19999; /* safe for 16 bit ints */
212				else
213					e = (int)L;
214				if (esign)
215					e = -e;
216				}
217			else
218				e = 0;
219			}
220		else
221			s = s00;
222		}
223	if (!nd) {
224		if (!nz && !nz0) {
225#ifdef INFNAN_CHECK
226			/* Check for Nan and Infinity */
227			ULong bits[2];
228			static FPI fpinan =	/* only 52 explicit bits */
229				{ 52, 1-1023-53+1, 2046-1023-53+1, 1, SI };
230			switch(c) {
231			  case 'i':
232			  case 'I':
233				if (match(&s,"nf")) {
234					--s;
235					if (!match(&s,"inity"))
236						++s;
237					word0(rv) = 0x7ff00000;
238					word1(rv) = 0;
239					goto ret;
240					}
241				break;
242			  case 'n':
243			  case 'N':
244				if (match(&s, "an")) {
245#ifndef No_Hex_NaN
246					if (*s == '(' /*)*/
247					 && hexnan(&s, &fpinan, bits)
248							== STRTOG_NaNbits) {
249						word0(rv) = 0x7ff00000 | bits[1];
250						word1(rv) = bits[0];
251						}
252					else {
253						word0(rv) = NAN_WORD0;
254						word1(rv) = NAN_WORD1;
255						}
256#endif
257					goto ret;
258					}
259			  }
260#endif /* INFNAN_CHECK */
261 ret0:
262			s = s00;
263			sign = 0;
264			}
265		goto ret;
266		}
267	e1 = e -= nf;
268
269	/* Now we have nd0 digits, starting at s0, followed by a
270	 * decimal point, followed by nd-nd0 digits.  The number we're
271	 * after is the integer represented by those digits times
272	 * 10**e */
273
274	if (!nd0)
275		nd0 = nd;
276	k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
277	dval(rv) = y;
278	if (k > 9) {
279#ifdef SET_INEXACT
280		if (k > DBL_DIG)
281			oldinexact = get_inexact();
282#endif
283		dval(rv) = tens[k - 9] * dval(rv) + z;
284		}
285	bd0 = 0;
286	if (nd <= DBL_DIG
287#ifndef RND_PRODQUOT
288#ifndef Honor_FLT_ROUNDS
289		&& Flt_Rounds == 1
290#endif
291#endif
292			) {
293		if (!e)
294			goto ret;
295		if (e > 0) {
296			if (e <= Ten_pmax) {
297#ifdef VAX
298				goto vax_ovfl_check;
299#else
300#ifdef Honor_FLT_ROUNDS
301				/* round correctly FLT_ROUNDS = 2 or 3 */
302				if (sign) {
303					rv = -rv;
304					sign = 0;
305					}
306#endif
307				/* rv = */ rounded_product(dval(rv), tens[e]);
308				goto ret;
309#endif
310				}
311			i = DBL_DIG - nd;
312			if (e <= Ten_pmax + i) {
313				/* A fancier test would sometimes let us do
314				 * this for larger i values.
315				 */
316#ifdef Honor_FLT_ROUNDS
317				/* round correctly FLT_ROUNDS = 2 or 3 */
318				if (sign) {
319					rv = -rv;
320					sign = 0;
321					}
322#endif
323				e -= i;
324				dval(rv) *= tens[i];
325#ifdef VAX
326				/* VAX exponent range is so narrow we must
327				 * worry about overflow here...
328				 */
329 vax_ovfl_check:
330				word0(rv) -= P*Exp_msk1;
331				/* rv = */ rounded_product(dval(rv), tens[e]);
332				if ((word0(rv) & Exp_mask)
333				 > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
334					goto ovfl;
335				word0(rv) += P*Exp_msk1;
336#else
337				/* rv = */ rounded_product(dval(rv), tens[e]);
338#endif
339				goto ret;
340				}
341			}
342#ifndef Inaccurate_Divide
343		else if (e >= -Ten_pmax) {
344#ifdef Honor_FLT_ROUNDS
345			/* round correctly FLT_ROUNDS = 2 or 3 */
346			if (sign) {
347				rv = -rv;
348				sign = 0;
349				}
350#endif
351			/* rv = */ rounded_quotient(dval(rv), tens[-e]);
352			goto ret;
353			}
354#endif
355		}
356	e1 += nd - k;
357
358#ifdef IEEE_Arith
359#ifdef SET_INEXACT
360	inexact = 1;
361	if (k <= DBL_DIG)
362		oldinexact = get_inexact();
363#endif
364#ifdef Avoid_Underflow
365	scale = 0;
366#endif
367#ifdef Honor_FLT_ROUNDS
368	if ((rounding = Flt_Rounds) >= 2) {
369		if (sign)
370			rounding = rounding == 2 ? 0 : 2;
371		else
372			if (rounding != 2)
373				rounding = 0;
374		}
375#endif
376#endif /*IEEE_Arith*/
377
378	/* Get starting approximation = rv * 10**e1 */
379
380	if (e1 > 0) {
381		if ( (i = e1 & 15) !=0)
382			dval(rv) *= tens[i];
383		if (e1 &= ~15) {
384			if (e1 > DBL_MAX_10_EXP) {
385 ovfl:
386#ifndef NO_ERRNO
387				errno = ERANGE;
388#endif
389				/* Can't trust HUGE_VAL */
390#ifdef IEEE_Arith
391#ifdef Honor_FLT_ROUNDS
392				switch(rounding) {
393				  case 0: /* toward 0 */
394				  case 3: /* toward -infinity */
395					word0(rv) = Big0;
396					word1(rv) = Big1;
397					break;
398				  default:
399					word0(rv) = Exp_mask;
400					word1(rv) = 0;
401				  }
402#else /*Honor_FLT_ROUNDS*/
403				word0(rv) = Exp_mask;
404				word1(rv) = 0;
405#endif /*Honor_FLT_ROUNDS*/
406#ifdef SET_INEXACT
407				/* set overflow bit */
408				dval(rv0) = 1e300;
409				dval(rv0) *= dval(rv0);
410#endif
411#else /*IEEE_Arith*/
412				word0(rv) = Big0;
413				word1(rv) = Big1;
414#endif /*IEEE_Arith*/
415				if (bd0)
416					goto retfree;
417				goto ret;
418				}
419			e1 >>= 4;
420			for(j = 0; e1 > 1; j++, e1 >>= 1)
421				if (e1 & 1)
422					dval(rv) *= bigtens[j];
423		/* The last multiplication could overflow. */
424			word0(rv) -= P*Exp_msk1;
425			dval(rv) *= bigtens[j];
426			if ((z = word0(rv) & Exp_mask)
427			 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
428				goto ovfl;
429			if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
430				/* set to largest number */
431				/* (Can't trust DBL_MAX) */
432				word0(rv) = Big0;
433				word1(rv) = Big1;
434				}
435			else
436				word0(rv) += P*Exp_msk1;
437			}
438		}
439	else if (e1 < 0) {
440		e1 = -e1;
441		if ( (i = e1 & 15) !=0)
442			dval(rv) /= tens[i];
443		if (e1 >>= 4) {
444			if (e1 >= 1 << n_bigtens)
445				goto undfl;
446#ifdef Avoid_Underflow
447			if (e1 & Scale_Bit)
448				scale = 2*P;
449			for(j = 0; e1 > 0; j++, e1 >>= 1)
450				if (e1 & 1)
451					dval(rv) *= tinytens[j];
452			if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask)
453						>> Exp_shift)) > 0) {
454				/* scaled rv is denormal; zap j low bits */
455				if (j >= 32) {
456					word1(rv) = 0;
457					if (j >= 53)
458					 word0(rv) = (P+2)*Exp_msk1;
459					else
460					 word0(rv) &= 0xffffffff << j-32;
461					}
462				else
463					word1(rv) &= 0xffffffff << j;
464				}
465#else
466			for(j = 0; e1 > 1; j++, e1 >>= 1)
467				if (e1 & 1)
468					dval(rv) *= tinytens[j];
469			/* The last multiplication could underflow. */
470			dval(rv0) = dval(rv);
471			dval(rv) *= tinytens[j];
472			if (!dval(rv)) {
473				dval(rv) = 2.*dval(rv0);
474				dval(rv) *= tinytens[j];
475#endif
476				if (!dval(rv)) {
477 undfl:
478					dval(rv) = 0.;
479#ifndef NO_ERRNO
480					errno = ERANGE;
481#endif
482					if (bd0)
483						goto retfree;
484					goto ret;
485					}
486#ifndef Avoid_Underflow
487				word0(rv) = Tiny0;
488				word1(rv) = Tiny1;
489				/* The refinement below will clean
490				 * this approximation up.
491				 */
492				}
493#endif
494			}
495		}
496
497	/* Now the hard part -- adjusting rv to the correct value.*/
498
499	/* Put digits into bd: true value = bd * 10^e */
500
501	bd0 = s2b(s0, nd0, nd, y);
502
503	for(;;) {
504		bd = Balloc(bd0->k);
505		Bcopy(bd, bd0);
506		bb = d2b(dval(rv), &bbe, &bbbits);	/* rv = bb * 2^bbe */
507		bs = i2b(1);
508
509		if (e >= 0) {
510			bb2 = bb5 = 0;
511			bd2 = bd5 = e;
512			}
513		else {
514			bb2 = bb5 = -e;
515			bd2 = bd5 = 0;
516			}
517		if (bbe >= 0)
518			bb2 += bbe;
519		else
520			bd2 -= bbe;
521		bs2 = bb2;
522#ifdef Honor_FLT_ROUNDS
523		if (rounding != 1)
524			bs2++;
525#endif
526#ifdef Avoid_Underflow
527		j = bbe - scale;
528		i = j + bbbits - 1;	/* logb(rv) */
529		if (i < Emin)	/* denormal */
530			j += P - Emin;
531		else
532			j = P + 1 - bbbits;
533#else /*Avoid_Underflow*/
534#ifdef Sudden_Underflow
535#ifdef IBM
536		j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
537#else
538		j = P + 1 - bbbits;
539#endif
540#else /*Sudden_Underflow*/
541		j = bbe;
542		i = j + bbbits - 1;	/* logb(rv) */
543		if (i < Emin)	/* denormal */
544			j += P - Emin;
545		else
546			j = P + 1 - bbbits;
547#endif /*Sudden_Underflow*/
548#endif /*Avoid_Underflow*/
549		bb2 += j;
550		bd2 += j;
551#ifdef Avoid_Underflow
552		bd2 += scale;
553#endif
554		i = bb2 < bd2 ? bb2 : bd2;
555		if (i > bs2)
556			i = bs2;
557		if (i > 0) {
558			bb2 -= i;
559			bd2 -= i;
560			bs2 -= i;
561			}
562		if (bb5 > 0) {
563			bs = pow5mult(bs, bb5);
564			bb1 = mult(bs, bb);
565			Bfree(bb);
566			bb = bb1;
567			}
568		if (bb2 > 0)
569			bb = lshift(bb, bb2);
570		if (bd5 > 0)
571			bd = pow5mult(bd, bd5);
572		if (bd2 > 0)
573			bd = lshift(bd, bd2);
574		if (bs2 > 0)
575			bs = lshift(bs, bs2);
576		delta = diff(bb, bd);
577		dsign = delta->sign;
578		delta->sign = 0;
579		i = cmp(delta, bs);
580#ifdef Honor_FLT_ROUNDS
581		if (rounding != 1) {
582			if (i < 0) {
583				/* Error is less than an ulp */
584				if (!delta->x[0] && delta->wds <= 1) {
585					/* exact */
586#ifdef SET_INEXACT
587					inexact = 0;
588#endif
589					break;
590					}
591				if (rounding) {
592					if (dsign) {
593						adj = 1.;
594						goto apply_adj;
595						}
596					}
597				else if (!dsign) {
598					adj = -1.;
599					if (!word1(rv)
600					 && !(word0(rv) & Frac_mask)) {
601						y = word0(rv) & Exp_mask;
602#ifdef Avoid_Underflow
603						if (!scale || y > 2*P*Exp_msk1)
604#else
605						if (y)
606#endif
607						  {
608						  delta = lshift(delta,Log2P);
609						  if (cmp(delta, bs) <= 0)
610							adj = -0.5;
611						  }
612						}
613 apply_adj:
614#ifdef Avoid_Underflow
615					if (scale && (y = word0(rv) & Exp_mask)
616						<= 2*P*Exp_msk1)
617					  word0(adj) += (2*P+1)*Exp_msk1 - y;
618#else
619#ifdef Sudden_Underflow
620					if ((word0(rv) & Exp_mask) <=
621							P*Exp_msk1) {
622						word0(rv) += P*Exp_msk1;
623						dval(rv) += adj*ulp(dval(rv));
624						word0(rv) -= P*Exp_msk1;
625						}
626					else
627#endif /*Sudden_Underflow*/
628#endif /*Avoid_Underflow*/
629					dval(rv) += adj*ulp(dval(rv));
630					}
631				break;
632				}
633			adj = ratio(delta, bs);
634			if (adj < 1.)
635				adj = 1.;
636			if (adj <= 0x7ffffffe) {
637				/* adj = rounding ? ceil(adj) : floor(adj); */
638				y = adj;
639				if (y != adj) {
640					if (!((rounding>>1) ^ dsign))
641						y++;
642					adj = y;
643					}
644				}
645#ifdef Avoid_Underflow
646			if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
647				word0(adj) += (2*P+1)*Exp_msk1 - y;
648#else
649#ifdef Sudden_Underflow
650			if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
651				word0(rv) += P*Exp_msk1;
652				adj *= ulp(dval(rv));
653				if (dsign)
654					dval(rv) += adj;
655				else
656					dval(rv) -= adj;
657				word0(rv) -= P*Exp_msk1;
658				goto cont;
659				}
660#endif /*Sudden_Underflow*/
661#endif /*Avoid_Underflow*/
662			adj *= ulp(dval(rv));
663			if (dsign)
664				dval(rv) += adj;
665			else
666				dval(rv) -= adj;
667			goto cont;
668			}
669#endif /*Honor_FLT_ROUNDS*/
670
671		if (i < 0) {
672			/* Error is less than half an ulp -- check for
673			 * special case of mantissa a power of two.
674			 */
675			if (dsign || word1(rv) || word0(rv) & Bndry_mask
676#ifdef IEEE_Arith
677#ifdef Avoid_Underflow
678			 || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1
679#else
680			 || (word0(rv) & Exp_mask) <= Exp_msk1
681#endif
682#endif
683				) {
684#ifdef SET_INEXACT
685				if (!delta->x[0] && delta->wds <= 1)
686					inexact = 0;
687#endif
688				break;
689				}
690			if (!delta->x[0] && delta->wds <= 1) {
691				/* exact result */
692#ifdef SET_INEXACT
693				inexact = 0;
694#endif
695				break;
696				}
697			delta = lshift(delta,Log2P);
698			if (cmp(delta, bs) > 0)
699				goto drop_down;
700			break;
701			}
702		if (i == 0) {
703			/* exactly half-way between */
704			if (dsign) {
705				if ((word0(rv) & Bndry_mask1) == Bndry_mask1
706				 &&  word1(rv) == (
707#ifdef Avoid_Underflow
708			(scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1)
709		? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
710#endif
711						   0xffffffff)) {
712					/*boundary case -- increment exponent*/
713					word0(rv) = (word0(rv) & Exp_mask)
714						+ Exp_msk1
715#ifdef IBM
716						| Exp_msk1 >> 4
717#endif
718						;
719					word1(rv) = 0;
720#ifdef Avoid_Underflow
721					dsign = 0;
722#endif
723					break;
724					}
725				}
726			else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
727 drop_down:
728				/* boundary case -- decrement exponent */
729#ifdef Sudden_Underflow /*{{*/
730				L = word0(rv) & Exp_mask;
731#ifdef IBM
732				if (L <  Exp_msk1)
733#else
734#ifdef Avoid_Underflow
735				if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1))
736#else
737				if (L <= Exp_msk1)
738#endif /*Avoid_Underflow*/
739#endif /*IBM*/
740					goto undfl;
741				L -= Exp_msk1;
742#else /*Sudden_Underflow}{*/
743#ifdef Avoid_Underflow
744				if (scale) {
745					L = word0(rv) & Exp_mask;
746					if (L <= (2*P+1)*Exp_msk1) {
747						if (L > (P+2)*Exp_msk1)
748							/* round even ==> */
749							/* accept rv */
750							break;
751						/* rv = smallest denormal */
752						goto undfl;
753						}
754					}
755#endif /*Avoid_Underflow*/
756				L = (word0(rv) & Exp_mask) - Exp_msk1;
757#endif /*Sudden_Underflow}*/
758				word0(rv) = L | Bndry_mask1;
759				word1(rv) = 0xffffffff;
760#ifdef IBM
761				goto cont;
762#else
763				break;
764#endif
765				}
766#ifndef ROUND_BIASED
767			if (!(word1(rv) & LSB))
768				break;
769#endif
770			if (dsign)
771				dval(rv) += ulp(dval(rv));
772#ifndef ROUND_BIASED
773			else {
774				dval(rv) -= ulp(dval(rv));
775#ifndef Sudden_Underflow
776				if (!dval(rv))
777					goto undfl;
778#endif
779				}
780#ifdef Avoid_Underflow
781			dsign = 1 - dsign;
782#endif
783#endif
784			break;
785			}
786		if ((aadj = ratio(delta, bs)) <= 2.) {
787			if (dsign)
788				aadj = aadj1 = 1.;
789			else if (word1(rv) || word0(rv) & Bndry_mask) {
790#ifndef Sudden_Underflow
791				if (word1(rv) == Tiny1 && !word0(rv))
792					goto undfl;
793#endif
794				aadj = 1.;
795				aadj1 = -1.;
796				}
797			else {
798				/* special case -- power of FLT_RADIX to be */
799				/* rounded down... */
800
801				if (aadj < 2./FLT_RADIX)
802					aadj = 1./FLT_RADIX;
803				else
804					aadj *= 0.5;
805				aadj1 = -aadj;
806				}
807			}
808		else {
809			aadj *= 0.5;
810			aadj1 = dsign ? aadj : -aadj;
811#ifdef Check_FLT_ROUNDS
812			switch(Rounding) {
813				case 2: /* towards +infinity */
814					aadj1 -= 0.5;
815					break;
816				case 0: /* towards 0 */
817				case 3: /* towards -infinity */
818					aadj1 += 0.5;
819				}
820#else
821			if (Flt_Rounds == 0)
822				aadj1 += 0.5;
823#endif /*Check_FLT_ROUNDS*/
824			}
825		y = word0(rv) & Exp_mask;
826
827		/* Check for overflow */
828
829		if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
830			dval(rv0) = dval(rv);
831			word0(rv) -= P*Exp_msk1;
832			adj = aadj1 * ulp(dval(rv));
833			dval(rv) += adj;
834			if ((word0(rv) & Exp_mask) >=
835					Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
836				if (word0(rv0) == Big0 && word1(rv0) == Big1)
837					goto ovfl;
838				word0(rv) = Big0;
839				word1(rv) = Big1;
840				goto cont;
841				}
842			else
843				word0(rv) += P*Exp_msk1;
844			}
845		else {
846#ifdef Avoid_Underflow
847			if (scale && y <= 2*P*Exp_msk1) {
848				if (aadj <= 0x7fffffff) {
849					if ((z = aadj) <= 0)
850						z = 1;
851					aadj = z;
852					aadj1 = dsign ? aadj : -aadj;
853					}
854				word0(aadj1) += (2*P+1)*Exp_msk1 - y;
855				}
856			adj = aadj1 * ulp(dval(rv));
857			dval(rv) += adj;
858#else
859#ifdef Sudden_Underflow
860			if ((word0(rv) & Exp_mask) <= P*Exp_msk1) {
861				dval(rv0) = dval(rv);
862				word0(rv) += P*Exp_msk1;
863				adj = aadj1 * ulp(dval(rv));
864				dval(rv) += adj;
865#ifdef IBM
866				if ((word0(rv) & Exp_mask) <  P*Exp_msk1)
867#else
868				if ((word0(rv) & Exp_mask) <= P*Exp_msk1)
869#endif
870					{
871					if (word0(rv0) == Tiny0
872					 && word1(rv0) == Tiny1)
873						goto undfl;
874					word0(rv) = Tiny0;
875					word1(rv) = Tiny1;
876					goto cont;
877					}
878				else
879					word0(rv) -= P*Exp_msk1;
880				}
881			else {
882				adj = aadj1 * ulp(dval(rv));
883				dval(rv) += adj;
884				}
885#else /*Sudden_Underflow*/
886			/* Compute adj so that the IEEE rounding rules will
887			 * correctly round rv + adj in some half-way cases.
888			 * If rv * ulp(rv) is denormalized (i.e.,
889			 * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
890			 * trouble from bits lost to denormalization;
891			 * example: 1.2e-307 .
892			 */
893			if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
894				aadj1 = (double)(int)(aadj + 0.5);
895				if (!dsign)
896					aadj1 = -aadj1;
897				}
898			adj = aadj1 * ulp(dval(rv));
899			dval(rv) += adj;
900#endif /*Sudden_Underflow*/
901#endif /*Avoid_Underflow*/
902			}
903		z = word0(rv) & Exp_mask;
904#ifndef SET_INEXACT
905#ifdef Avoid_Underflow
906		if (!scale)
907#endif
908		if (y == z) {
909			/* Can we stop now? */
910			L = (Long)aadj;
911			aadj -= L;
912			/* The tolerances below are conservative. */
913			if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
914				if (aadj < .4999999 || aadj > .5000001)
915					break;
916				}
917			else if (aadj < .4999999/FLT_RADIX)
918				break;
919			}
920#endif
921 cont:
922		Bfree(bb);
923		Bfree(bd);
924		Bfree(bs);
925		Bfree(delta);
926		}
927#ifdef SET_INEXACT
928	if (inexact) {
929		if (!oldinexact) {
930			word0(rv0) = Exp_1 + (70 << Exp_shift);
931			word1(rv0) = 0;
932			dval(rv0) += 1.;
933			}
934		}
935	else if (!oldinexact)
936		clear_inexact();
937#endif
938#ifdef Avoid_Underflow
939	if (scale) {
940		word0(rv0) = Exp_1 - 2*P*Exp_msk1;
941		word1(rv0) = 0;
942		dval(rv) *= dval(rv0);
943#ifndef NO_ERRNO
944		/* try to avoid the bug of testing an 8087 register value */
945		if (word0(rv) == 0 && word1(rv) == 0)
946			errno = ERANGE;
947#endif
948		}
949#endif /* Avoid_Underflow */
950#ifdef SET_INEXACT
951	if (inexact && !(word0(rv) & Exp_mask)) {
952		/* set underflow bit */
953		dval(rv0) = 1e-300;
954		dval(rv0) *= dval(rv0);
955		}
956#endif
957 retfree:
958	Bfree(bb);
959	Bfree(bd);
960	Bfree(bs);
961	Bfree(bd0);
962	Bfree(delta);
963 ret:
964	if (se)
965		*se = (char *)s;
966	return sign ? -dval(rv) : dval(rv);
967	}
968
969