in src/crt_abstractions.c [477:571]
static FLOAT_STRING_TYPE splitFloatString(const char* nptr, char** endptr, int *signal, double *fraction, int *exponential)
{
FLOAT_STRING_TYPE result = FST_ERROR;
unsigned long long ullInteger = 0;
unsigned long long ullFraction = 0;
int integerSize = 0;
int fractionSize = 0;
char* startptr;
(*endptr) = (char*)nptr;
/*Codes_SRS_CRT_ABSTRACTIONS_21_018: [The white-space for strtof_s must be one of the characters ' ', '\f', '\n', '\r', '\t', '\v'.]*/
/*Codes_SRS_CRT_ABSTRACTIONS_21_028: [The white-space for strtold_s must be one of the characters ' ', '\f', '\n', '\r', '\t', '\v'.]*/
while (IS_SPACE(**endptr))
{
(*endptr)++;
}
/*Codes_SRS_CRT_ABSTRACTIONS_21_019: [The valid sequence for strtof_s starts after the first non-white - space character, followed by an optional positive or negative sign, a number, 'INF', or 'NAN' (ignoring case).]*/
/*Codes_SRS_CRT_ABSTRACTIONS_21_029: [The valid sequence for strtold_s starts after the first non-white - space character, followed by an optional positive or negative sign, a number, 'INF', or 'NAN' (ignoring case).]*/
(*signal) = +1;
if ((**endptr) == '+')
{
(*endptr)++;
}
else if ((**endptr) == '-')
{
(*signal) = -1;
(*endptr)++;
}
/*Codes_SRS_CRT_ABSTRACTIONS_21_023: [If the string is 'INF' of 'INFINITY' (ignoring case), the strtof_s must return the INFINITY value for float.]*/
/*Codes_SRS_CRT_ABSTRACTIONS_21_033: [If the string is 'INF' of 'INFINITY' (ignoring case), the strtold_s must return the INFINITY value for long double.]*/
if (isInfinity((const char**)endptr))
{
result = FST_INFINITY;
}
/*Codes_SRS_CRT_ABSTRACTIONS_21_034: [If the string is 'NAN' or 'NAN(...)' (ignoring case), the strtold_s must return 0.0 and points endptr to the first character after the 'NAN' sequence.]*/
/*Codes_SRS_CRT_ABSTRACTIONS_21_024: [If the string is 'NAN' or 'NAN(...)' (ignoring case), the strtof_s must return 0.0f and points endptr to the first character after the 'NAN' sequence.]*/
else if (isNaN((const char**)endptr))
{
result = FST_NAN;
}
else if (IN_BASE_RANGE(DIGIT_VAL(**endptr), 10))
{
result = FST_NUMBER;
startptr = *endptr;
/* integers will go to the fraction and exponential. */
ullInteger = strtoull_s(startptr, endptr, 10);
integerSize = (int)((*endptr) - startptr);
if ((ullInteger == ULLONG_MAX) && (errno != 0))
{
result = FST_OVERFLOW;
}
/* get the real fraction part, if exist. */
if ((**endptr) == '.')
{
startptr = (*endptr) + 1;
ullFraction = strtoull_s(startptr, endptr, 10);
fractionSize = (int)((*endptr) - startptr);
if ((ullFraction == ULLONG_MAX) && (errno != 0))
{
result = FST_OVERFLOW;
}
}
if (((**endptr) == 'e') || ((**endptr) == 'E'))
{
startptr = (*endptr) + 1;
(*exponential) = (int)strtol(startptr, endptr, 10);
if (((*exponential) < (DBL_MAX_10_EXP * (-1))) || ((*exponential) > DBL_MAX_10_EXP))
{
result = FST_OVERFLOW;
}
}
else
{
(*exponential) = 0;
}
if (result == FST_NUMBER)
{
/* Add ullInteger to ullFraction. */
ullFraction += (ullInteger * (unsigned long long)(pow(10, (double)fractionSize)));
(*fraction) = ((double)ullFraction / (pow(10.0f, ((double)fractionSize + (double)integerSize - 1.00))));
/* Unify rest of integerSize and fractionSize in the exponential. */
(*exponential) += integerSize - 1;
}
}
return result;
}