/* * PROJECT: ReactOS CRT * LICENSE: See COPYING in the top level directory * PURPOSE: CRT's ecvt * FILE: lib/sdk/crt/stdlib/ecvt.c * PROGRAMERS: Gregor Schneider (parts based on ecvtbuf.c by DJ Delorie) */ #include #define NUMBER_EFMT 18 /* sign, dot, null, 15 for alignment */ /* * @implemented */ char * _ecvt (double value, int ndigits, int *decpt, int *sign) { static char ecvtbuf[DBL_MAX_10_EXP + 10]; char *cvtbuf, *s, *d; if (ndigits < 0) ndigits = 0; s = cvtbuf = (char*)malloc(ndigits + NUMBER_EFMT); d = ecvtbuf; *sign = 0; *decpt = 0; if (cvtbuf == NULL) { return NULL; } sprintf(cvtbuf, "%-+.*E", ndigits, value); /* Treat special values */ if (strncmp(s, "NaN", 3) == 0) { memcpy(ecvtbuf, s, 4); } else if (strncmp(s + 1, "Inf", 3) == 0) { memcpy(ecvtbuf, s, 5); } else { /* Set the sign */ if (*s && *s == '-') { *sign = 1; } s++; /* Copy the first digit */ if (*s && *s != '.') { if (d - ecvtbuf < ndigits) { *d++ = *s++; } else { s++; } } /* Skip the decimal point */ if (*s && *s == '.') { s++; } /* Copy fractional digits */ while (*s && *s != 'E') { if (d - ecvtbuf < ndigits) { *d++ = *s++; } else { s++; } } /* Skip the exponent */ if (*s && *s == 'E') { s++; } /* Set the decimal point to the exponent value plus the one digit we copied */ *decpt = atoi(s) + 1; /* Handle special decimal point cases */ if (cvtbuf[1] == '0') { *decpt = 0; } if (ndigits < 1) { /* Need enhanced precision*/ char* tbuf = (char*)malloc(NUMBER_EFMT); if (tbuf == NULL) { free(cvtbuf); return NULL; } sprintf(tbuf, "%-+.*E", ndigits + 2, value); if (tbuf[1] >= '5') { (*decpt)++; } free(tbuf); } /* Pad with zeroes */ while (d - ecvtbuf < ndigits) { *d++ = '0'; } /* Terminate */ *d = '\0'; } free(cvtbuf); return ecvtbuf; }