149 constexpr auto inf = std::numeric_limits<double>::infinity();
151 bool isNegative =
false;
153 constexpr const int maxSignificantDigits = 17 + 1;
154 constexpr const int bufferSize = maxSignificantDigits + 7 + 1;
155 char buffer[(size_t) bufferSize] = {};
156 char* writePtr = &(buffer[0]);
159 const auto endOfWhitspace = text.findEndOfWhitespace();
160 text = endOfWhitspace;
184 if ((text[1] ==
'a' || text[1] ==
'A') && (text[2] ==
'n' || text[2] ==
'N'))
187 return std::numeric_limits<double>::quiet_NaN();
190 text = endOfWhitspace;
197 if ((text[1] ==
'n' || text[1] ==
'N') && (text[2] ==
'f' || text[2] ==
'F'))
200 return isNegative ? -inf : inf;
203 text = endOfWhitspace;
214 double result[3] = { 0 }, accumulator[2] = { 0 };
215 int exponentAdjustment[2] = { 0 }, exponentAccumulator[2] = { -1, -1 };
216 int exponent = 0, decPointIndex = 0, digit = 0;
217 int lastDigit = 0, numSignificantDigits = 0;
218 bool digitsFound =
false;
219 constexpr const int maxSignificantDigits = 17 + 1;
226 digit = (int) text.getAndAdvance() -
'0';
229 if (decPointIndex != 0)
230 exponentAdjustment[1]++;
232 if (numSignificantDigits == 0 && digit == 0)
235 if (++numSignificantDigits > maxSignificantDigits)
238 ++accumulator [decPointIndex];
239 else if (digit == 5 && (lastDigit & 1) != 0)
240 ++accumulator [decPointIndex];
242 if (decPointIndex > 0)
243 exponentAdjustment[1]--;
245 exponentAdjustment[0]++;
247 while (text.isDigit())
250 if (decPointIndex == 0)
251 exponentAdjustment[0]++;
256 const auto maxAccumulatorValue = (double) ((std::numeric_limits<unsigned int>::max() - 9) / 10);
257 if (accumulator [decPointIndex] > maxAccumulatorValue)
259 result [decPointIndex] = mulexp10 (result [decPointIndex], exponentAccumulator [decPointIndex])
260 + accumulator [decPointIndex];
261 accumulator [decPointIndex] = 0;
262 exponentAccumulator [decPointIndex] = 0;
265 accumulator [decPointIndex] = accumulator[decPointIndex] * 10 + digit;
266 exponentAccumulator [decPointIndex]++;
269 else if (decPointIndex == 0 && *text ==
'.')
274 if (numSignificantDigits > maxSignificantDigits)
276 while (text.isDigit())
287 result[0] = mulexp10 (result[0], exponentAccumulator[0]) + accumulator[0];
289 if (decPointIndex != 0)
290 result[1] = mulexp10 (result[1], exponentAccumulator[1]) + accumulator[1];
293 if ((c ==
'e' || c ==
'E') && digitsFound)
295 auto negativeExponent =
false;
299 case '-': negativeExponent =
true; JUCE_FALLTHROUGH
303 while (text.isDigit())
304 exponent = (exponent * 10) + ((
int) text.getAndAdvance() -
'0');
306 if (negativeExponent)
307 exponent = -exponent;
310 auto r = mulexp10 (result[0], exponent + exponentAdjustment[0]);
311 if (decPointIndex != 0)
312 r += mulexp10 (result[1], exponent - exponentAdjustment[1]);
314 return isNegative ? -r : r;
318 int numSigFigs = 0, extraExponent = 0;
319 bool decimalPointFound =
false, leadingZeros =
false;
325 auto digit = (int) text.getAndAdvance() -
'0';
327 if (decimalPointFound)
329 if (numSigFigs >= maxSignificantDigits)
334 if (numSigFigs >= maxSignificantDigits)
340 if (numSigFigs == 0 && digit == 0)
347 *writePtr++ = (char) (
'0' + (
char) digit);
350 else if ((! decimalPointFound) && *text ==
'.')
354 decimalPointFound =
true;
362 if ((! leadingZeros) && (numSigFigs == 0))
364 text = endOfWhitspace;
368 auto writeExponentDigits = [] (
int exponent,
char* destination)
370 auto exponentDivisor = 100;
372 while (exponentDivisor > 1)
374 auto digit = exponent / exponentDivisor;
375 *destination++ = (char) (
'0' + (
char) digit);
376 exponent -= digit * exponentDivisor;
377 exponentDivisor /= 10;
380 *destination++ = (char) (
'0' + (
char) exponent);
385 if (c ==
'e' || c ==
'E')
387 const auto startOfExponent = text;
389 bool parsedExponentIsPositive =
true;
394 parsedExponentIsPositive =
false;
404 const auto startOfExponentDigits = text;
406 while (text.isDigit())
408 auto digit = (int) text.getAndAdvance() -
'0';
410 if (digit != 0 || exponent != 0)
411 exponent = (exponent * 10) + digit;
414 if (text == startOfExponentDigits)
415 text = startOfExponent;
417 exponent = extraExponent + (parsedExponentIsPositive ? exponent : -exponent);
421 if (exponent < std::numeric_limits<double>::min_exponent10 - 1)
422 return isNegative ? -0.0 : 0.0;
425 exponent = -exponent;
427 else if (exponent > std::numeric_limits<double>::max_exponent10 + 1)
429 return isNegative ? -inf : inf;
432 writeExponentDigits (exponent, writePtr);
434 else if (extraExponent > 0)
437 writeExponentDigits (extraExponent, writePtr);
441 static _locale_t locale = _create_locale (LC_ALL,
"C");
442 return _strtod_l (&buffer[0],
nullptr, locale);
444 static locale_t locale = newlocale (LC_ALL_MASK,
"C",
nullptr);
446 return (
double) strtold_l (&buffer[0],
nullptr, locale);
448 return strtod_l (&buffer[0],
nullptr, locale);