ReactOS  0.4.14-dev-854-gb9426a3
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  */
15 char *
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 }
static size_t double int int int * sign
Definition: printf.c:69
#define free
Definition: debug_ros.c:5
#define NUMBER_EFMT
Definition: ecvt.c:10
#define DBL_MAX_10_EXP
Definition: gcc_float.h:97
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static size_t double int int * decpt
Definition: printf.c:69
smooth NULL
Definition: ftsmooth.c:416
static size_t double int ndigits
Definition: printf.c:69
#define d
Definition: ke_i.h:81
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLdouble s
Definition: gl.h:2039
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
#define malloc
Definition: debug_ros.c:4
char * _ecvt(double value, int ndigits, int *decpt, int *sign)
Definition: ecvt.c:16