4coder-non-source/test_data/lots_of_files/xstoxflt.c

119 lines
3.4 KiB
C

/* _Stoxflt function */
#include "xmath.h"
#include <ctype.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
_C_STD_BEGIN
#if !defined(MRTDLL)
_C_LIB_DECL
#endif /* defined(MRTDLL) */
#define BASE 16 /* hexadecimal */
#define NDIG 7 /* hexadecimal digits per long element */
#define MAXSIG (5 * NDIG) /* maximum significant digits to keep */
_CRTIMP2_PURE int __CLRCALL_PURE_OR_CDECL _Stoxflt(const char *s0, const char *s,
char **endptr, long lo[], int maxsig)
{ /* convert 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 */
const char *pd;
static const char digits[] = "0123456789abcdefABCDEF";
static const char vals[] =
{ /* values of hex digits */
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
10, 11, 12, 13, 14, 15};
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 == '0'; ++s, seen = 1)
; /* strip leading zeros */
for (nsig = 0; (pd = (char *)memchr(&digits[0], *s, 22)) != 0;
++s, seen = 1)
if (nsig <= maxsig)
buf[nsig++] = vals[pd - digits]; /* accumulate a digit */
else
++lo[0]; /* too many digits, just scale exponent */
if (*s == localeconv()->decimal_point[0])
++s;
if (nsig == 0)
for (; *s == '0'; ++s, seen = 1)
--lo[0]; /* strip zeros after point */
for (; (pd = (char *)memchr(&digits[0], *s, 22)) != 0; ++s, seen = 1)
if (nsig <= maxsig)
{ /* accumulate a fraction digit */
buf[nsig++] = vals[pd - digits];
--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 */
lo[0] <<= 2; /* change hex exponent to binary exponent */
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 == 'p' || *s == 'P')
{ /* parse exponent */
const char *ssav = s;
const char esign = *++s == '+' || *s == '-' ? *s++ : '+';
int eseen = 0;
long lexp = 0;
for (; isdigit((unsigned char)*s); ++s, eseen = 1)
if (lexp < 100000000) /* else overflow */
lexp = lexp * 10 + (unsigned char)*s - '0';
if (esign == '-')
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 = (char *)(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 */