1 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
7 // #include <msvcrt/locale.h>
9 void __ecvround (char *, char *, const char *, int *);
12 __ecvround (char *numbuf
, char *last_digit
, const char *after_last
, int *decpt
)
17 /* Do we have at all to round the last digit? */
18 if (*after_last
> '4')
23 /* Propagate the rounding through trailing '9' digits. */
27 *p
-- = sum
- carry
* 10;
28 } while (carry
&& p
>= numbuf
);
30 /* We have 9999999... which needs to be rounded to 100000.. */
31 if (carry
&& p
== numbuf
)
40 ecvtbuf (double value
, int ndigits
, int *decpt
, int *sign
, char *buf
)
42 static char INFINITY
[] = "Infinity";
43 char decimal
= '.' /* localeconv()->decimal_point[0] */;
44 char *cvtbuf
= (char *)_alloca (ndigits
+ 20); /* +3 for sign, dot, null; */
45 /* two extra for rounding */
46 /* 15 extra for alignment */
47 char *s
= cvtbuf
, *d
= buf
;
49 /* Produce two extra digits, so we could round properly. */
50 sprintf (cvtbuf
, "%-+.*E", ndigits
+ 2, value
);
59 /* Special values get special treatment. */
60 if (strncmp (s
, "Inf", 3) == 0)
62 /* SunOS docs says we have return "Infinity" for NDIGITS >= 8. */
63 memcpy (buf
, INFINITY
, ndigits
>= 8 ? 9 : 3);
67 else if (strcmp (s
, "NaN") == 0)
71 char *last_digit
, *digit_after_last
;
73 /* Copy (the single) digit before the decimal. */
74 while (*s
&& *s
!= decimal
&& d
- buf
< ndigits
)
77 /* If we don't see any exponent, here's our decimal point. */
82 /* Copy the fraction digits. */
83 while (*s
&& *s
!= 'E' && d
- buf
< ndigits
)
86 /* Remember the last digit copied and the one after it. */
87 last_digit
= d
> buf
? d
- 1 : d
;
90 /* Get past the E in exponent field. */
91 while (*s
&& *s
++ != 'E')
94 /* Adjust the decimal point by the exponent value. */
97 /* Pad with zeroes if needed. */
98 while (d
- buf
< ndigits
)
101 /* Zero-terminate. */
104 /* Round if necessary. */
105 __ecvround (buf
, last_digit
, digit_after_last
, decpt
);