/* _WStoflt function */ #include #include #include #include "xmath.h" _C_STD_BEGIN #if !defined(MRTDLL) _C_LIB_DECL #endif /* defined(MRTDLL) */ #define BASE 10 /* decimal */ #define NDIG 9 /* decimal digits per long element */ #define MAXSIG (5 * NDIG) /* maximum significant digits to keep */ _CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _WStoflt(const wchar_t *s0, const wchar_t *s, wchar_t **endptr, long lo[], int maxsig) { /* convert wide string to array of long plus exponent */ char buf[MAXSIG + 1]; /* worst case, with room for rounding digit */ int nsig; /* number of significant digits seen */ int seen; /* any valid field characters seen */ int word = 0; /* current long word to fill */ maxsig *= NDIG; /* convert word count to digit count */ if (MAXSIG < maxsig) maxsig = MAXSIG; /* protect against bad call */ lo[0] = 0; /* power of ten exponent */ lo[1] = 0; /* first NDIG-digit word of fraction */ for (seen = 0; *s == L'0'; ++s, seen = 1) ; /* strip leading zeros */ for (nsig = 0; iswdigit(*s); ++s, seen = 1) if (nsig <= maxsig) buf[nsig++] = (char)(*s - L'0'); /* accumulate a digit */ else ++lo[0]; /* too many digits, just scale exponent */ if (*s == btowc(localeconv()->decimal_point[0])) ++s; if (nsig == 0) for (; *s == L'0'; ++s, seen = 1) --lo[0]; /* scale for stripped zeros after point */ for (; iswdigit(*s); ++s, seen = 1) if (nsig <= maxsig) { /* accumulate a fraction digit */ buf[nsig++] = (char)(*s - L'0'); --lo[0]; } if (maxsig < nsig) { /* discard excess digit after rounding up */ unsigned int ms = maxsig; /* to quiet warnings */ if (BASE / 2 <= buf[ms]) ++buf[ms - 1]; /* okay if digit becomes BASE */ nsig = maxsig; ++lo[0]; } for (; 0 < nsig && buf[nsig - 1] == '\0'; --nsig) ++lo[0]; /* discard trailing zeros */ if (nsig == 0) buf[nsig++] = '\0'; /* ensure at least one digit */ if (seen) { /* convert digit sequence to words */ int bufidx = 0; /* next digit in buffer */ int wordidx = NDIG - nsig % NDIG; /* next digit in word (% NDIG) */ word = wordidx % NDIG == 0 ? 0 : 1; for (; bufidx < nsig; ++wordidx, ++bufidx) if (wordidx % NDIG == 0) lo[++word] = buf[bufidx]; else lo[word] = lo[word] * BASE + buf[bufidx]; if (*s == L'e' || *s == L'E') { /* parse exponent */ const wchar_t *ssav = s; const wchar_t esign = *++s == L'+' || *s == L'-' ? *s++ : L'+'; int eseen = 0; long lexp = 0; for (; iswdigit(*s); ++s, eseen = 1) if (lexp < 100000000) /* else overflow */ lexp = lexp * 10 + *s - L'0'; if (esign == L'-') lexp = -lexp; lo[0] += lexp; if (!eseen) s = ssav; /* roll back if incomplete exponent */ } } if (!seen) word = 0; /* return zero if bad parse */ if (endptr) *endptr = (wchar_t *)(seen ? s : s0); /* roll back if bad parse */ return (word); } #if !defined(MRTDLL) _END_C_LIB_DECL #endif /* !defined(MRTDLL) */ _C_STD_END /* * Copyright (c) 1992-2012 by P.J. Plauger. ALL RIGHTS RESERVED. * Consult your license regarding permissions and restrictions. V6.00:0009 */