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