in src/Elastic.Apm/Libraries/Newtonsoft.Json/Utilities/ConvertUtils.cs [1057:1215]
public static ParseResult DoubleTryParse(char[] chars, int start, int length, out double value)
{
value = 0;
if (length == 0)
{
return ParseResult.Invalid;
}
bool isNegative = (chars[start] == '-');
if (isNegative)
{
// text just a negative sign
if (length == 1)
{
return ParseResult.Invalid;
}
start++;
length--;
}
int i = start;
int end = start + length;
int numDecimalStart = end;
int numDecimalEnd = end;
int exponent = 0;
ulong mantissa = 0UL;
int mantissaDigits = 0;
int exponentFromMantissa = 0;
for (; i < end; i++)
{
char c = chars[i];
switch (c)
{
case '.':
if (i == start)
{
return ParseResult.Invalid;
}
if (i + 1 == end)
{
return ParseResult.Invalid;
}
if (numDecimalStart != end)
{
// multiple decimal points
return ParseResult.Invalid;
}
numDecimalStart = i + 1;
break;
case 'e':
case 'E':
if (i == start)
{
return ParseResult.Invalid;
}
if (i == numDecimalStart)
{
// E follows decimal point
return ParseResult.Invalid;
}
i++;
if (i == end)
{
return ParseResult.Invalid;
}
if (numDecimalStart < end)
{
numDecimalEnd = i - 1;
}
c = chars[i];
bool exponentNegative = false;
switch (c)
{
case '-':
exponentNegative = true;
i++;
break;
case '+':
i++;
break;
}
// parse 3 digit
for (; i < end; i++)
{
c = chars[i];
if (c < '0' || c > '9')
{
return ParseResult.Invalid;
}
int newExponent = (10 * exponent) + (c - '0');
// stops updating exponent when overflowing
if (exponent < newExponent)
{
exponent = newExponent;
}
}
if (exponentNegative)
{
exponent = -exponent;
}
break;
default:
if (c < '0' || c > '9')
{
return ParseResult.Invalid;
}
if (i == start && c == '0')
{
i++;
if (i != end)
{
c = chars[i];
if (c == '.')
{
goto case '.';
}
if (c == 'e' || c == 'E')
{
goto case 'E';
}
return ParseResult.Invalid;
}
}
if (mantissaDigits < 19)
{
mantissa = (10 * mantissa) + (ulong)(c - '0');
if (mantissa > 0)
{
++mantissaDigits;
}
}
else
{
++exponentFromMantissa;
}
break;
}
}
exponent += exponentFromMantissa;
// correct the decimal point
exponent -= (numDecimalEnd - numDecimalStart);
value = IEEE754.PackDouble(isNegative, mantissa, exponent);
return double.IsInfinity(value) ? ParseResult.Overflow : ParseResult.Success;
}