Embedded Artistry libc
C Standard Library Support for Bare-metal Systems
strtod.c File Reference
#include "gdtoaimp.h"
#include <float.h>
#include <math.h>
#include <stdint.h>
#include <fenv.h>
Include dependency graph for strtod.c:

Go to the source code of this file.

Macros

#define Rounding   Flt_Rounds
 
#define fpi1   fpi
 

Functions

double strtod (CONST char *s00, char **se)
 

Macro Definition Documentation

◆ fpi1

#define fpi1   fpi

◆ Rounding

#define Rounding   Flt_Rounds

Definition at line 59 of file strtod.c.

Function Documentation

◆ strtod()

double strtod ( CONST char *  s00,
char **  se 
)

Definition at line 67 of file strtod.c.

69 {
70 #ifdef Avoid_Underflow
71  int scale;
72 #endif
73  int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign, e, e1, esign, i, j, k, nd, nd0, nf,
74  nz, nz0, sign;
75  CONST char *s, *s0, *s1;
76  double aadj, aadj1, adj, rv, rv0;
77  Long L;
78  ULong y, z;
79  Bigint *bb = NULL, *bb1 = NULL, *bd = NULL, *bd0 = NULL, *bs = NULL, *delta = NULL;
80 #ifdef SET_INEXACT
81  int inexact, oldinexact;
82 #endif
83 #ifdef Honor_FLT_ROUNDS
84  int rounding;
85 #endif
86 
87  sign = nz0 = nz = decpt = 0;
88  dval(rv) = 0.;
89  for(s = s00;; s++)
90  {
91  switch(*s)
92  {
93  case '-':
94  sign = 1;
95  /* no break */
96  case '+':
97  if(*++s)
98  {
99  goto break2;
100  }
101  /* no break */
102  case 0:
103  goto ret0;
104  case '\t':
105  case '\n':
106  case '\v':
107  case '\f':
108  case '\r':
109  case ' ':
110  continue;
111  default:
112  goto break2;
113  }
114  }
115 break2:
116  if(*s == '0')
117  {
118 #ifndef NO_HEX_FP
119  {
120  static FPI fpi = {53, 1 - 1023 - 53 + 1, 2046 - 1023 - 53 + 1, 1, SI};
121  Long exp;
122  ULong bits[2];
123  switch(s[1])
124  {
125  case 'x':
126  case 'X':
127  {
128 #if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD)
129  FPI fpi1 = fpi;
130  switch(fegetround())
131  {
132  case FE_TOWARDZERO:
133  fpi1.rounding = 0;
134  break;
135  case FE_UPWARD:
136  fpi1.rounding = 2;
137  break;
138  case FE_DOWNWARD:
139  fpi1.rounding = 3;
140  }
141 #else
142 #define fpi1 fpi
143 #endif
144  switch((i = gethex(&s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask)
145  {
146  case STRTOG_NoNumber:
147  s = s00;
148  sign = 0;
149  case STRTOG_Zero:
150  break;
151  default:
152  if(bb)
153  {
154  copybits(bits, fpi.nbits, bb);
155  Bfree(bb);
156  }
157  ULtod(((U*)&rv)->L, bits, exp, i);
158  }
159  }
160  goto ret;
161  }
162  }
163 #endif
164  nz0 = 1;
165  while(*++s == '0')
166  {
167  }
168 
169  if(!*s)
170  {
171  goto ret;
172  }
173  }
174  s0 = s;
175  y = z = 0;
176  for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
177  {
178  if(nd < 9)
179  {
180  y = 10 * y + (unsigned)c - '0';
181  }
182  else if(nd < 16)
183  {
184  z = 10 * z + (unsigned)c - '0';
185  }
186  }
187  nd0 = nd;
188 #ifdef USE_LOCALE
189  if(c == *localeconv()->decimal_point)
190 #else
191  if(c == '.')
192 #endif
193  {
194  decpt = 1;
195  c = *++s;
196  if(!nd)
197  {
198  for(; c == '0'; c = *++s)
199  {
200  nz++;
201  }
202  if(c > '0' && c <= '9')
203  {
204  s0 = s;
205  nf += nz;
206  nz = 0;
207  goto have_dig;
208  }
209  goto dig_done;
210  }
211  for(; c >= '0' && c <= '9'; c = *++s)
212  {
213  have_dig:
214  nz++;
215  if(c -= '0')
216  {
217  nf += nz;
218  for(i = 1; i < nz; i++)
219  {
220  if(nd++ < 9)
221  {
222  y *= 10;
223  }
224  else if(nd <= DBL_DIG + 1)
225  {
226  z *= 10;
227  }
228  }
229  if(nd++ < 9)
230  {
231  y = 10 * y + (unsigned)c;
232  }
233  else if(nd <= DBL_DIG + 1)
234  {
235  z = 10 * z + (unsigned)c;
236  }
237  nz = 0;
238  }
239  }
240  }
241 dig_done:
242  e = 0;
243  if(c == 'e' || c == 'E')
244  {
245  if(!nd && !nz && !nz0)
246  {
247  goto ret0;
248  }
249  s00 = s;
250  esign = 0;
251  switch(c = *++s)
252  {
253  case '-':
254  esign = 1;
255  case '+':
256  c = *++s;
257  }
258  if(c >= '0' && c <= '9')
259  {
260  while(c == '0')
261  {
262  c = *++s;
263  }
264  if(c > '0' && c <= '9')
265  {
266  L = c - '0';
267  s1 = s;
268  while((c = *++s) >= '0' && c <= '9')
269  {
270  L = 10 * L + c - '0';
271  }
272  if(s - s1 > 8 || L > 19999)
273  {
274  /* Avoid confusion from exponents
275  * so large that e might overflow.
276  */
277  e = 19999; /* safe for 16 bit ints */
278  }
279  else
280  {
281  e = (int)L;
282  }
283  if(esign)
284  {
285  e = -e;
286  }
287  }
288  else
289  {
290  e = 0;
291  }
292  }
293  else
294  {
295  s = s00;
296  }
297  }
298  if(!nd)
299  {
300  if(!nz && !nz0)
301  {
302 #ifdef INFNAN_CHECK
303  /* Check for Nan and Infinity */
304  ULong bits[2];
305  static FPI fpinan = /* only 52 explicit bits */
306  {52, 1 - 1023 - 53 + 1, 2046 - 1023 - 53 + 1, 1, SI};
307  if(!decpt)
308  switch(c)
309  {
310  case 'i':
311  case 'I':
312  if(match(&s, "nf"))
313  {
314  --s;
315  if(!match(&s, "inity"))
316  ++s;
317  word0(rv) = 0x7ff00000;
318  word1(rv) = 0;
319  goto ret;
320  }
321  break;
322  case 'n':
323  case 'N':
324  if(match(&s, "an"))
325  {
326 #ifndef No_Hex_NaN
327  if(*s == '(' /*)*/
328  && hexnan(&s, &fpinan, bits) == STRTOG_NaNbits)
329  {
330  word0(rv) = 0x7ff00000 | bits[1];
331  word1(rv) = bits[0];
332  }
333  else
334  {
335 #endif
336  word0(rv) = NAN_WORD0;
337  word1(rv) = NAN_WORD1;
338 #ifndef No_Hex_NaN
339  }
340 #endif
341  goto ret;
342  }
343  }
344 #endif /* INFNAN_CHECK */
345  ret0:
346  s = s00;
347  sign = 0;
348  }
349  goto ret;
350  }
351  e1 = e -= nf;
352 
353  /* Now we have nd0 digits, starting at s0, followed by a
354  * decimal point, followed by nd-nd0 digits. The number we're
355  * after is the integer represented by those digits times
356  * 10**e */
357 
358  if(!nd0)
359  {
360  nd0 = nd;
361  }
362  k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
363  dval(rv) = y;
364  if(k > 9)
365  {
366 #ifdef SET_INEXACT
367  if(k > DBL_DIG)
368  oldinexact = get_inexact();
369 #endif
370  dval(rv) = tens[k - 9] * dval(rv) + z;
371  }
372  bd0 = 0;
373  if(nd <= DBL_DIG
374 #ifndef RND_PRODQUOT
375 #ifndef Honor_FLT_ROUNDS
376  && Flt_Rounds == 1
377 #endif
378 #endif
379  )
380  {
381  if(!e)
382  {
383  goto ret;
384  }
385  if(e > 0)
386  {
387  if(e <= Ten_pmax)
388  {
389 #ifdef VAX
390  goto vax_ovfl_check;
391 #else
392 #ifdef Honor_FLT_ROUNDS
393  /* round correctly FLT_ROUNDS = 2 or 3 */
394  if(sign)
395  {
396  rv = -rv;
397  sign = 0;
398  }
399 #endif
400  /* rv = */ rounded_product(dval(rv), tens[e]);
401  goto ret;
402 #endif
403  }
404  i = DBL_DIG - nd;
405  if(e <= Ten_pmax + i)
406  {
407  /* A fancier test would sometimes let us do
408  * this for larger i values.
409  */
410 #ifdef Honor_FLT_ROUNDS
411  /* round correctly FLT_ROUNDS = 2 or 3 */
412  if(sign)
413  {
414  rv = -rv;
415  sign = 0;
416  }
417 #endif
418  e -= i;
419  dval(rv) *= tens[i];
420 #ifdef VAX
421  /* VAX exponent range is so narrow we must
422  * worry about overflow here...
423  */
424  vax_ovfl_check:
425  word0(rv) -= P * Exp_msk1;
426  /* rv = */ rounded_product(dval(rv), tens[e]);
427  if((word0(rv) & Exp_mask) > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P))
428  {
429  goto ovfl;
430  }
431  word0(rv) += P * Exp_msk1;
432 #else
433  /* rv = */ rounded_product(dval(rv), tens[e]);
434 #endif
435  goto ret;
436  }
437  }
438 #ifndef Inaccurate_Divide
439  else if(e >= -Ten_pmax)
440  {
441 #ifdef Honor_FLT_ROUNDS
442  /* round correctly FLT_ROUNDS = 2 or 3 */
443  if(sign)
444  {
445  rv = -rv;
446  sign = 0;
447  }
448 #endif
449  /* rv = */ rounded_quotient(dval(rv), tens[-e]);
450  goto ret;
451  }
452 #endif
453  }
454  e1 += nd - k;
455 
456 #ifdef IEEE_Arith
457 #ifdef SET_INEXACT
458  inexact = 1;
459  if(k <= DBL_DIG)
460  {
461  oldinexact = get_inexact();
462  }
463 #endif
464 #ifdef Avoid_Underflow
465  scale = 0;
466 #endif
467 #ifdef Honor_FLT_ROUNDS
468  if((rounding = Flt_Rounds) >= 2)
469  {
470  if(sign)
471  {
472  rounding = rounding == 2 ? 0 : 2;
473  }
474  else if(rounding != 2)
475  {
476  rounding = 0;
477  }
478  }
479 #endif
480 #endif /*IEEE_Arith*/
481 
482  /* Get starting approximation = rv * 10**e1 */
483 
484  if(e1 > 0)
485  {
486  if((i = e1 & 15) != 0)
487  {
488  dval(rv) *= tens[i];
489  }
490  if(e1 &= ~15)
491  {
492  if(e1 > DBL_MAX_10_EXP)
493  {
494  ovfl:
495 #ifndef NO_ERRNO
496  errno = ERANGE;
497 #endif
498  /* Can't trust HUGE_VAL */
499 #ifdef IEEE_Arith
500 #ifdef Honor_FLT_ROUNDS
501  switch(rounding)
502  {
503  case 0: /* toward 0 */
504  case 3: /* toward -infinity */
505  word0(rv) = Big0;
506  word1(rv) = Big1;
507  break;
508  default:
509  word0(rv) = Exp_mask;
510  word1(rv) = 0;
511  }
512 #else /*Honor_FLT_ROUNDS*/
513  word0(rv) = Exp_mask;
514  word1(rv) = 0;
515 #endif /*Honor_FLT_ROUNDS*/
516 #ifdef SET_INEXACT
517  /* set overflow bit */
518  dval(rv0) = 1e300;
519  dval(rv0) *= dval(rv0);
520 #endif
521 #else /*IEEE_Arith*/
522  word0(rv) = Big0;
523  word1(rv) = Big1;
524 #endif /*IEEE_Arith*/
525  if(bd0)
526  {
527  goto retfree;
528  }
529  goto ret;
530  }
531  e1 >>= 4;
532  for(j = 0; e1 > 1; j++, e1 >>= 1)
533  {
534  if(e1 & 1)
535  {
536  dval(rv) *= bigtens[j];
537  }
538  }
539  /* The last multiplication could overflow. */
540  word0(rv) -= P * Exp_msk1;
541  dval(rv) *= bigtens[j];
542  if((z = word0(rv) & Exp_mask) > Exp_msk1 * (DBL_MAX_EXP + Bias - P))
543  {
544  goto ovfl;
545  }
546  if(z > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P))
547  {
548  /* set to largest number */
549  /* (Can't trust DBL_MAX) */
550  word0(rv) = Big0;
551  word1(rv) = Big1;
552  }
553  else
554  {
555  word0(rv) += P * Exp_msk1;
556  }
557  }
558  }
559  else if(e1 < 0)
560  {
561  e1 = -e1;
562  if((i = e1 & 15) != 0)
563  {
564  dval(rv) /= tens[i];
565  }
566  if(e1 >>= 4)
567  {
568  if(e1 >= 1 << n_bigtens)
569  {
570  goto undfl;
571  }
572 #ifdef Avoid_Underflow
573  if(e1 & Scale_Bit)
574  {
575  scale = 2 * P;
576  }
577  for(j = 0; e1 > 0; j++, e1 >>= 1)
578  {
579  if(e1 & 1)
580  {
581  dval(rv) *= tinytens[j];
582  }
583  }
584  if(scale && (j = 2 * P + 1 - ((word0(rv) & Exp_mask) >> Exp_shift)) > 0)
585  {
586  /* scaled rv is denormal; zap j low bits */
587  if(j >= 32)
588  {
589  word1(rv) = 0;
590  if(j >= 53)
591  {
592  word0(rv) = (P + 2) * Exp_msk1;
593  }
594  else
595  {
596  word0(rv) &= 0xffffffff << (j - 32);
597  }
598  }
599  else
600  {
601  word1(rv) &= 0xffffffff << j;
602  }
603  }
604 #else
605  for(j = 0; e1 > 1; j++, e1 >>= 1)
606  {
607  if(e1 & 1)
608  {
609  dval(rv) *= tinytens[j];
610  }
611  }
612  /* The last multiplication could underflow. */
613  dval(rv0) = dval(rv);
614  dval(rv) *= tinytens[j];
615  if(!dval(rv))
616  {
617  dval(rv) = 2. * dval(rv0);
618  dval(rv) *= tinytens[j];
619 #endif
620  if(fabs(dval(rv)) <= DBL_EPSILON)
621  {
622  undfl:
623  dval(rv) = 0.;
624 #ifndef NO_ERRNO
625  errno = ERANGE;
626 #endif
627  if(bd0)
628  {
629  goto retfree;
630  }
631  goto ret;
632  }
633 #ifndef Avoid_Underflow
634  word0(rv) = Tiny0;
635  word1(rv) = Tiny1;
636  /* The refinement below will clean
637  * this approximation up.
638  */
639  }
640 #endif
641  }
642 }
643 
644 /* Now the hard part -- adjusting rv to the correct value.*/
645 
646 /* Put digits into bd: true value = bd * 10^e */
647 
648 bd0 = s2b(s0, nd0, nd, y);
649 
650 for(;;)
651 {
652  bd = Balloc(bd0->k);
653  Bcopy(bd, bd0);
654  bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */
655  bs = i2b(1);
656 
657  if(e >= 0)
658  {
659  bb2 = bb5 = 0;
660  bd2 = bd5 = e;
661  }
662  else
663  {
664  bb2 = bb5 = -e;
665  bd2 = bd5 = 0;
666  }
667  if(bbe >= 0)
668  {
669  bb2 += bbe;
670  }
671  else
672  {
673  bd2 -= bbe;
674  }
675  bs2 = bb2;
676 #ifdef Honor_FLT_ROUNDS
677  if(rounding != 1)
678  {
679  bs2++;
680  }
681 #endif
682 #ifdef Avoid_Underflow
683  j = bbe - scale;
684  i = j + bbbits - 1; /* logb(rv) */
685  if(i < Emin) /* denormal */
686  {
687  j += P - Emin;
688  }
689  else
690  {
691  j = P + 1 - bbbits;
692  }
693 #else /*Avoid_Underflow*/
694 #ifdef Sudden_Underflow
695 #ifdef IBM
696  j = 1 + 4 * P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
697 #else
698  j = P + 1 - bbbits;
699 #endif
700 #else /*Sudden_Underflow*/
701  j = bbe;
702  i = j + bbbits - 1; /* logb(rv) */
703  if(i < Emin) /* denormal */
704  {
705  j += P - Emin;
706  }
707  else
708  {
709  j = P + 1 - bbbits;
710  }
711 #endif /*Sudden_Underflow*/
712 #endif /*Avoid_Underflow*/
713  bb2 += j;
714  bd2 += j;
715 #ifdef Avoid_Underflow
716  bd2 += scale;
717 #endif
718  i = bb2 < bd2 ? bb2 : bd2;
719  if(i > bs2)
720  {
721  i = bs2;
722  }
723  if(i > 0)
724  {
725  bb2 -= i;
726  bd2 -= i;
727  bs2 -= i;
728  }
729  if(bb5 > 0)
730  {
731  bs = pow5mult(bs, bb5);
732  bb1 = mult(bs, bb);
733  Bfree(bb);
734  bb = bb1;
735  }
736  if(bb2 > 0)
737  {
738  bb = lshift(bb, bb2);
739  }
740  if(bd5 > 0)
741  {
742  bd = pow5mult(bd, bd5);
743  }
744  if(bd2 > 0)
745  {
746  bd = lshift(bd, bd2);
747  }
748  if(bs2 > 0)
749  {
750  bs = lshift(bs, bs2);
751  }
752  delta = diff(bb, bd);
753  dsign = delta->sign;
754  delta->sign = 0;
755  i = cmp(delta, bs);
756 #ifdef Honor_FLT_ROUNDS
757  if(rounding != 1)
758  {
759  if(i < 0)
760  {
761  /* Error is less than an ulp */
762  if(!delta->x[0] && delta->wds <= 1)
763  {
764  /* exact */
765 #ifdef SET_INEXACT
766  inexact = 0;
767 #endif
768  break;
769  }
770  if(rounding)
771  {
772  if(dsign)
773  {
774  adj = 1.;
775  goto apply_adj;
776  }
777  }
778  else if(!dsign)
779  {
780  adj = -1.;
781  if(!word1(rv) && !(word0(rv) & Frac_mask))
782  {
783  y = word0(rv) & Exp_mask;
784 #ifdef Avoid_Underflow
785  if(!scale || y > 2 * P * Exp_msk1)
786 #else
787  if(y)
788 #endif
789  {
790  delta = lshift(delta, Log2P);
791  if(cmp(delta, bs) <= 0)
792  {
793  adj = -0.5;
794  }
795  }
796  }
797  apply_adj:
798 #ifdef Avoid_Underflow
799  if(scale && (y = word0(rv) & Exp_mask) <= 2 * P * Exp_msk1)
800  {
801  word0(adj) += (2 * P + 1) * Exp_msk1 - y;
802  }
803 #else
804 #ifdef Sudden_Underflow
805  if((word0(rv) & Exp_mask) <= P * Exp_msk1)
806  {
807  word0(rv) += P * Exp_msk1;
808  dval(rv) += adj * ulp(dval(rv));
809  word0(rv) -= P * Exp_msk1;
810  }
811  else
812 #endif /*Sudden_Underflow*/
813 #endif /*Avoid_Underflow*/
814  dval(rv) += adj * ulp(dval(rv));
815  }
816  break;
817  }
818  adj = ratio(delta, bs);
819  if(adj < 1.)
820  {
821  adj = 1.;
822  }
823  if(adj <= 0x7ffffffe)
824  {
825  /* adj = rounding ? ceil(adj) : floor(adj); */
826  y = (ULong)adj;
827  if(fabs(y - adj) > DBL_EPSILON)
828  {
829  if(!((rounding >> 1) ^ dsign))
830  {
831  y++;
832  }
833  adj = y;
834  }
835  }
836 #ifdef Avoid_Underflow
837  if(scale && (y = word0(rv) & Exp_mask) <= (2 * P * Exp_msk1))
838  {
839  word0(adj) += (2 * P + 1) * Exp_msk1 - y;
840  }
841 #else
842 #ifdef Sudden_Underflow
843  if((word0(rv) & Exp_mask) <= P * Exp_msk1)
844  {
845  word0(rv) += P * Exp_msk1;
846  adj *= ulp(dval(rv));
847  if(dsign)
848  {
849  dval(rv) += adj;
850  }
851  else
852  {
853  dval(rv) -= adj;
854  }
855  word0(rv) -= P * Exp_msk1;
856  goto cont;
857  }
858 #endif /*Sudden_Underflow*/
859 #endif /*Avoid_Underflow*/
860  adj *= ulp(dval(rv));
861  if(dsign)
862  {
863  dval(rv) += adj;
864  }
865  else
866  {
867  dval(rv) -= adj;
868  }
869  goto cont;
870  }
871 #endif /*Honor_FLT_ROUNDS*/
872 
873  if(i < 0)
874  {
875  /* Error is less than half an ulp -- check for
876  * special case of mantissa a power of two.
877  */
878  if(dsign || word1(rv) || word0(rv) & Bndry_mask
879 #ifdef IEEE_Arith
880 #ifdef Avoid_Underflow
881  || (word0(rv) & Exp_mask) <= (2 * P + 1) * Exp_msk1
882 #else
883  || (word0(rv) & Exp_mask) <= Exp_msk1
884 #endif
885 #endif
886  )
887  {
888 #ifdef SET_INEXACT
889  if(!delta->x[0] && delta->wds <= 1)
890  {
891  inexact = 0;
892  }
893 #endif
894  break;
895  }
896  if(!delta->x[0] && delta->wds <= 1)
897  {
898  /* exact result */
899 #ifdef SET_INEXACT
900  inexact = 0;
901 #endif
902  break;
903  }
904  delta = lshift(delta, Log2P);
905  if(cmp(delta, bs) > 0)
906  {
907  goto drop_down;
908  }
909  break;
910  }
911  if(i == 0)
912  {
913  /* exactly half-way between */
914  if(dsign)
915  {
916  if((word0(rv) & Bndry_mask1) == Bndry_mask1 &&
917  word1(rv) == (
918 #ifdef Avoid_Underflow
919  (scale && (y = word0(rv) & Exp_mask) <= 2 * P * Exp_msk1)
920  ? (0xffffffff & (0xffffffff << (2 * P + 1 - (y >> Exp_shift))))
921  :
922 #endif
923  0xffffffff))
924  {
925  /*boundary case -- increment exponent*/
926  word0(rv) = (word0(rv) & Exp_mask) + Exp_msk1
927 #ifdef IBM
928  | Exp_msk1 >> 4
929 #endif
930  ;
931  word1(rv) = 0;
932 #ifdef Avoid_Underflow
933  dsign = 0;
934 #endif
935  break;
936  }
937  }
938  else if(!(word0(rv) & Bndry_mask) && !word1(rv))
939  {
940  drop_down:
941  /* boundary case -- decrement exponent */
942 #ifdef Sudden_Underflow /*{{*/
943  L = word0(rv) & Exp_mask;
944 #ifdef IBM
945  if(L < Exp_msk1)
946 #else
947 #ifdef Avoid_Underflow
948  if(L <= (scale ? (2 * P + 1) * Exp_msk1 : Exp_msk1))
949 #else
950  if(L <= Exp_msk1)
951 #endif /*Avoid_Underflow*/
952 #endif /*IBM*/
953  goto undfl;
954  L -= Exp_msk1;
955 #else /*Sudden_Underflow}{*/
956 #ifdef Avoid_Underflow
957  if(scale)
958  {
959  L = word0(rv) & Exp_mask;
960  if(L <= (2 * P + 1) * Exp_msk1)
961  {
962  if(L > (P + 2) * Exp_msk1)
963  {
964  /* round even ==> */
965  /* accept rv */
966  break;
967  }
968  /* rv = smallest denormal */
969  goto undfl;
970  }
971  }
972 #endif /*Avoid_Underflow*/
973  L = (word0(rv) & Exp_mask) - Exp_msk1;
974 #endif /*Sudden_Underflow}*/
975  word0(rv) = (ULong)(L | Bndry_mask1);
976  word1(rv) = 0xffffffff;
977 #ifdef IBM
978  goto cont;
979 #else
980  break;
981 #endif
982  }
983 #ifndef ROUND_BIASED
984  if(!(word1(rv) & LSB))
985  {
986  break;
987  }
988 #endif
989  if(dsign)
990  {
991  dval(rv) += ulp(dval(rv));
992  }
993 #ifndef ROUND_BIASED
994  else
995  {
996  dval(rv) -= ulp(dval(rv));
997 #ifndef Sudden_Underflow
998  if(fabs(dval(rv)) <= DBL_EPSILON)
999  {
1000  goto undfl;
1001  }
1002 #endif
1003  }
1004 #ifdef Avoid_Underflow
1005  dsign = 1 - dsign;
1006 #endif
1007 #endif
1008  break;
1009  }
1010  if((aadj = ratio(delta, bs)) <= 2.)
1011  {
1012  if(dsign)
1013  {
1014  aadj = aadj1 = 1.;
1015  }
1016  else if(word1(rv) || word0(rv) & Bndry_mask)
1017  {
1018 #ifndef Sudden_Underflow
1019  if(word1(rv) == Tiny1 && !word0(rv))
1020  {
1021  goto undfl;
1022  }
1023 #endif
1024  aadj = 1.;
1025  aadj1 = -1.;
1026  }
1027  else
1028  {
1029  /* special case -- power of FLT_RADIX to be */
1030  /* rounded down... */
1031 
1032  if(aadj < 2. / FLT_RADIX)
1033  {
1034  aadj = 1. / FLT_RADIX;
1035  }
1036  else
1037  {
1038  aadj *= 0.5;
1039  }
1040  aadj1 = -aadj;
1041  }
1042  }
1043  else
1044  {
1045  aadj *= 0.5;
1046  aadj1 = dsign ? aadj : -aadj;
1047 #ifdef Check_FLT_ROUNDS
1048  switch(Rounding)
1049  {
1050  case 2: /* towards +infinity */
1051  aadj1 -= 0.5;
1052  break;
1053  case 0: /* towards 0 */
1054  case 3: /* towards -infinity */
1055  aadj1 += 0.5;
1056  }
1057 #else
1058  if(Flt_Rounds == 0)
1059  {
1060  aadj1 += 0.5;
1061  }
1062 #endif /*Check_FLT_ROUNDS*/
1063  }
1064  y = word0(rv) & Exp_mask;
1065 
1066  /* Check for overflow */
1067 
1068  if(y == Exp_msk1 * (DBL_MAX_EXP + Bias - 1))
1069  {
1070  dval(rv0) = dval(rv);
1071  word0(rv) -= P * Exp_msk1;
1072  adj = aadj1 * ulp(dval(rv));
1073  dval(rv) += adj;
1074  if((word0(rv) & Exp_mask) >= Exp_msk1 * (DBL_MAX_EXP + Bias - P))
1075  {
1076  if(word0(rv0) == Big0 && word1(rv0) == Big1)
1077  {
1078  goto ovfl;
1079  }
1080  word0(rv) = Big0;
1081  word1(rv) = Big1;
1082  goto cont;
1083  }
1084  else
1085  {
1086  word0(rv) += P * Exp_msk1;
1087  }
1088  }
1089  else
1090  {
1091 #ifdef Avoid_Underflow
1092  if(scale && y <= 2 * P * Exp_msk1)
1093  {
1094  if(aadj <= 0x7fffffff)
1095  {
1096  z = (ULong)aadj;
1097  if(z <= 0)
1098  {
1099  z = 1;
1100  }
1101  aadj = z;
1102  aadj1 = dsign ? aadj : -aadj;
1103  }
1104  word0(aadj1) += (2 * P + 1) * Exp_msk1 - y;
1105  }
1106  adj = aadj1 * ulp(dval(rv));
1107  dval(rv) += adj;
1108 #else
1109 #ifdef Sudden_Underflow
1110  if((word0(rv) & Exp_mask) <= P * Exp_msk1)
1111  {
1112  dval(rv0) = dval(rv);
1113  word0(rv) += P * Exp_msk1;
1114  adj = aadj1 * ulp(dval(rv));
1115  dval(rv) += adj;
1116 #ifdef IBM
1117  if((word0(rv) & Exp_mask) < P * Exp_msk1)
1118 #else
1119  if((word0(rv) & Exp_mask) <= P * Exp_msk1)
1120 #endif
1121  {
1122  if(word0(rv0) == Tiny0 && word1(rv0) == Tiny1)
1123  {
1124  goto undfl;
1125  }
1126  word0(rv) = Tiny0;
1127  word1(rv) = Tiny1;
1128  goto cont;
1129  }
1130  else
1131  {
1132  word0(rv) -= P * Exp_msk1;
1133  }
1134  }
1135  else
1136  {
1137  adj = aadj1 * ulp(dval(rv));
1138  dval(rv) += adj;
1139  }
1140 #else /*Sudden_Underflow*/
1141  /* Compute adj so that the IEEE rounding rules will
1142  * correctly round rv + adj in some half-way cases.
1143  * If rv * ulp(rv) is denormalized (i.e.,
1144  * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
1145  * trouble from bits lost to denormalization;
1146  * example: 1.2e-307 .
1147  */
1148  if(y <= (P - 1) * Exp_msk1 && aadj > 1.)
1149  {
1150  aadj1 = (double)(int)(aadj + 0.5);
1151  if(!dsign)
1152  {
1153  aadj1 = -aadj1;
1154  }
1155  }
1156  adj = aadj1 * ulp(dval(rv));
1157  dval(rv) += adj;
1158 #endif /*Sudden_Underflow*/
1159 #endif /*Avoid_Underflow*/
1160  }
1161  z = word0(rv) & Exp_mask;
1162 #ifndef SET_INEXACT
1163 #ifdef Avoid_Underflow
1164  if(!scale)
1165  {
1166 #endif
1167  if(y == z)
1168  {
1169  /* Can we stop now? */
1170  L = (Long)aadj;
1171  aadj -= L;
1172  /* The tolerances below are conservative. */
1173  if(dsign || word1(rv) || word0(rv) & Bndry_mask)
1174  {
1175  if(aadj < .4999999 || aadj > .5000001)
1176  {
1177  break;
1178  }
1179  }
1180  else if(aadj < .4999999 / FLT_RADIX)
1181  {
1182  break;
1183  }
1184  }
1185 #ifdef Avoid_Underflow
1186  }
1187 #endif
1188 #endif
1189 cont:
1190  Bfree(bb);
1191  Bfree(bd);
1192  Bfree(bs);
1193  Bfree(delta);
1194 }
1195 #ifdef SET_INEXACT
1196 if(inexact)
1197 {
1198  if(!oldinexact)
1199  {
1200  word0(rv0) = Exp_1 + (70 << Exp_shift);
1201  word1(rv0) = 0;
1202  dval(rv0) += 1.;
1203  }
1204 }
1205 else if(!oldinexact)
1206 {
1207  clear_inexact();
1208 }
1209 #endif
1210 #ifdef Avoid_Underflow
1211 if(scale)
1212 {
1213  word0(rv0) = Exp_1 - 2 * P * Exp_msk1;
1214  word1(rv0) = 0;
1215  dval(rv) *= dval(rv0);
1216 #ifndef NO_ERRNO
1217  /* try to avoid the bug of testing an 8087 register value */
1218  if(word0(rv) == 0 && word1(rv) == 0)
1219  {
1220  errno = ERANGE;
1221  }
1222 #endif
1223 }
1224 #endif /* Avoid_Underflow */
1225 #ifdef SET_INEXACT
1226 if(inexact && !(word0(rv) & Exp_mask))
1227 {
1228  /* set underflow bit */
1229  dval(rv0) = 1e-300;
1230  dval(rv0) *= dval(rv0);
1231 }
1232 #endif
1233 retfree : if(bb)
1234 {
1235  Bfree(bb);
1236 }
1237 
1238 if(bd)
1239 {
1240  Bfree(bd);
1241 }
1242 
1243 if(bs)
1244 {
1245  Bfree(bs);
1246 }
1247 
1248 if(bd0)
1249 {
1250  Bfree(bd0);
1251 }
1252 
1253 if(delta)
1254 {
1255  Bfree(delta);
1256 }
1257 
1258 ret : if(se)
1259 {
1260  *se = (char*)(uintptr_t)s;
1261 }
1262 return sign ? -dval(rv) : dval(rv);
1263 }
int errno
#define Ten_pmax
Definition: gdtoaimp.h:406
int hexnan(CONST char **sp, FPI *fpi, ULong *x0)
Definition: hexnan.c:61
#define Tiny0
Definition: gdtoaimp.h:413
#define bigtens
Definition: gdtoaimp.h:514
#define DBL_MAX_EXP
Definition: float.h:42
#define P
Definition: gdtoaimp.h:399
Bigint * i2b(int i)
Definition: misc.c:271
#define Flt_Rounds
Definition: gdtoaimp.h:393
#define Bias
Definition: gdtoaimp.h:400
#define DBL_MAX_10_EXP
Definition: float.h:48
Definition: gdtoaimp.h:284
#define CONST
Definition: gdtoa.h:61
Bigint * lshift(Bigint *b, int k)
Definition: misc.c:495
#define Big1
Definition: gdtoaimp.h:438
#define Exp_msk1
Definition: gdtoaimp.h:396
#define Tiny1
Definition: gdtoaimp.h:414
#define word1(x)
Definition: gdtoaimp.h:305
#define Bndry_mask
Definition: gdtoaimp.h:408
#define FLT_RADIX
Definition: float.h:14
#define fpi1
Bigint * diff(Bigint *a, Bigint *b)
Definition: misc.c:617
#define Bcopy(x, y)
Definition: gdtoaimp.h:501
#define tens
Definition: gdtoaimp.h:544
#define match
Definition: gdtoaimp.h:530
#define dval(x)
Definition: gdtoaimp.h:307
#define ERANGE
Definition: errno.h:50
int nbits
Definition: gdtoa.h:88
#define word0(x)
Definition: gdtoaimp.h:304
struct lconv * localeconv(void)
#define NULL
Definition: stddef.h:15
int gethex(CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign)
Definition: gethex.c:46
#define SI
Definition: gdtoaimp.h:635
Bigint * d2b(double d, int *e, int *bits)
Definition: misc.c:798
#define rounded_product(a, b)
Definition: gdtoaimp.h:433
static Akind IBM
Definition: arithchk.c:36
#define rounded_quotient(a, b)
Definition: gdtoaimp.h:434
#define Exp_1
Definition: gdtoaimp.h:401
double ratio(Bigint *a, Bigint *b)
Definition: smisc.c:96
unsigned Long ULong
Definition: gdtoa.h:41
void copybits(ULong *c, int n, Bigint *b)
Definition: smisc.c:171
void Bfree(Bigint *v)
Definition: misc.c:92
#define tinytens
Definition: gdtoaimp.h:546
Bigint * s2b(CONST char *s, int nd0, int nd, ULong y9)
Definition: smisc.c:40
double fabs(double)
Definition: fabs.c:4
#define Rounding
Definition: strtod.c:59
#define Bndry_mask1
Definition: gdtoaimp.h:409
void ULtod(ULong *L, const ULong *bits, Long exp, int k)
Definition: strtord.c:41
#define Exp_mask
Definition: gdtoaimp.h:398
#define Honor_FLT_ROUNDS
Definition: arith.h:49
Bigint * pow5mult(Bigint *b, int k)
Definition: misc.c:420
#define LSB
Definition: gdtoaimp.h:410
int cmp(Bigint *a, Bigint *b)
Definition: misc.c:570
Definition: gdtoa.h:86
#define Log2P
Definition: gdtoaimp.h:412
Bigint * Balloc(int k)
Definition: misc.c:47
#define Frac_mask
Definition: gdtoaimp.h:404
#define DBL_DIG
Definition: float.h:45
Bigint * mult(Bigint *a, Bigint *b)
Definition: misc.c:287
#define Exp_shift
Definition: gdtoaimp.h:394
double ulp(double x)
Definition: ulp.c:38
#define Long
Definition: gdtoa.h:38
#define DBL_EPSILON
Definition: float.h:38
#define Big0
Definition: gdtoaimp.h:437
char * decimal_point
Definition: locale.h:20

References Balloc(), Bcopy, Bfree(), Bias, Big0, Big1, bigtens, Bndry_mask, Bndry_mask1, cmp(), CONST, copybits(), d2b(), DBL_DIG, DBL_EPSILON, DBL_MAX_10_EXP, DBL_MAX_EXP, lconv::decimal_point, diff(), dval, ERANGE, errno, Exp_1, Exp_mask, Exp_msk1, Exp_shift, fabs(), FLT_RADIX, Flt_Rounds, fpi1, Frac_mask, gethex(), hexnan(), Honor_FLT_ROUNDS, i2b(), IBM, localeconv(), Log2P, Long, LSB, lshift(), match, mult(), FPI::nbits, NULL, P, pow5mult(), ratio(), rounded_product, rounded_quotient, Rounding, s2b(), SI, STRTOG_NaNbits, STRTOG_NoNumber, STRTOG_Retmask, STRTOG_Zero, Ten_pmax, tens, Tiny0, Tiny1, tinytens, ulp(), ULtod(), word0, and word1.