ReactOS 0.4.16-dev-258-g81860b4
ecvt.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS CRT
3 * LICENSE: See COPYING in the top level directory
4 * PURPOSE: CRT's ecvt
5 * FILE: lib/sdk/crt/stdlib/ecvt.c
6 * PROGRAMERS: Gregor Schneider (parts based on ecvtbuf.c by DJ Delorie)
7 */
8
9#include <precomp.h>
10#define NUMBER_EFMT 18 /* sign, dot, null, 15 for alignment */
11
12/*
13 * @implemented
14 */
15char *
16_ecvt (double value, int ndigits, int *decpt, int *sign)
17{
18 static char ecvtbuf[DBL_MAX_10_EXP + 10];
19 char *cvtbuf, *s, *d;
20
21 if (ndigits < 0) ndigits = 0;
22 s = cvtbuf = (char*)malloc(ndigits + NUMBER_EFMT);
23 d = ecvtbuf;
24
25 *sign = 0;
26 *decpt = 0;
27
28 if (cvtbuf == NULL)
29 {
30 return NULL;
31 }
32
33 sprintf(cvtbuf, "%-+.*E", ndigits, value);
34 /* Treat special values */
35 if (strncmp(s, "NaN", 3) == 0)
36 {
37 memcpy(ecvtbuf, s, 4);
38 }
39 else if (strncmp(s + 1, "Inf", 3) == 0)
40 {
41 memcpy(ecvtbuf, s, 5);
42 }
43 else
44 {
45 /* Set the sign */
46 if (*s && *s == '-')
47 {
48 *sign = 1;
49 }
50 s++;
51 /* Copy the first digit */
52 if (*s && *s != '.')
53 {
54 if (d - ecvtbuf < ndigits)
55 {
56 *d++ = *s++;
57 }
58 else
59 {
60 s++;
61 }
62 }
63 /* Skip the decimal point */
64 if (*s && *s == '.')
65 {
66 s++;
67 }
68 /* Copy fractional digits */
69 while (*s && *s != 'E')
70 {
71 if (d - ecvtbuf < ndigits)
72 {
73 *d++ = *s++;
74 }
75 else
76 {
77 s++;
78 }
79 }
80 /* Skip the exponent */
81 if (*s && *s == 'E')
82 {
83 s++;
84 }
85 /* Set the decimal point to the exponent value plus the one digit we copied */
86 *decpt = atoi(s) + 1;
87 /* Handle special decimal point cases */
88 if (cvtbuf[1] == '0')
89 {
90 *decpt = 0;
91 }
92 if (ndigits < 1)
93 {
94 /* Need enhanced precision*/
95 char* tbuf = (char*)malloc(NUMBER_EFMT);
96 if (tbuf == NULL)
97 {
98 free(cvtbuf);
99 return NULL;
100 }
101 sprintf(tbuf, "%-+.*E", ndigits + 2, value);
102 if (tbuf[1] >= '5')
103 {
104 (*decpt)++;
105 }
106 free(tbuf);
107 }
108 /* Pad with zeroes */
109 while (d - ecvtbuf < ndigits)
110 {
111 *d++ = '0';
112 }
113 /* Terminate */
114 *d = '\0';
115 }
116 free(cvtbuf);
117 return ecvtbuf;
118}
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define NUMBER_EFMT
Definition: ecvt.c:10
char * _ecvt(double value, int ndigits, int *decpt, int *sign)
Definition: ecvt.c:16
#define DBL_MAX_10_EXP
Definition: gcc_float.h:97
GLdouble s
Definition: gl.h:2039
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
#define d
Definition: ke_i.h:81
#define sign(x)
Definition: mapdesc.cc:613
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static size_t double int ndigits
Definition: printf.c:72
static size_t double int int * decpt
Definition: printf.c:72
Definition: pdh_main.c:94