150 bool isNegative =
false;
152 JUCE_CONSTEXPR
const int maxSignificantDigits = 17 + 1;
153 JUCE_CONSTEXPR
const int bufferSize = maxSignificantDigits + 7 + 1;
154 char buffer[(size_t) bufferSize] = {};
155 char* currentCharacter = &(buffer[0]);
158 text = text.findEndOfWhitespace();
167 *currentCharacter++ =
'-';
178 if ((text[1] ==
'a' || text[1] ==
'A') && (text[2] ==
'n' || text[2] ==
'N'))
179 return std::numeric_limits<double>::quiet_NaN();
184 if ((text[1] ==
'n' || text[1] ==
'N') && (text[2] ==
'f' || text[2] ==
'F'))
185 return std::numeric_limits<double>::infinity();
192 double result[3] = { 0 }, accumulator[2] = { 0 };
193 int exponentAdjustment[2] = { 0 }, exponentAccumulator[2] = { -1, -1 };
194 int exponent = 0, decPointIndex = 0, digit = 0;
195 int lastDigit = 0, numSignificantDigits = 0;
196 bool digitsFound =
false;
197 JUCE_CONSTEXPR
const int maxSignificantDigits = 17 + 1;
204 digit = (int) text.getAndAdvance() -
'0';
207 if (decPointIndex != 0)
208 exponentAdjustment[1]++;
210 if (numSignificantDigits == 0 && digit == 0)
213 if (++numSignificantDigits > maxSignificantDigits)
216 ++accumulator [decPointIndex];
217 else if (digit == 5 && (lastDigit & 1) != 0)
218 ++accumulator [decPointIndex];
220 if (decPointIndex > 0)
221 exponentAdjustment[1]--;
223 exponentAdjustment[0]++;
225 while (text.isDigit())
228 if (decPointIndex == 0)
229 exponentAdjustment[0]++;
234 const auto maxAccumulatorValue = (double) ((std::numeric_limits<unsigned int>::max() - 9) / 10);
235 if (accumulator [decPointIndex] > maxAccumulatorValue)
237 result [decPointIndex] = mulexp10 (result [decPointIndex], exponentAccumulator [decPointIndex])
238 + accumulator [decPointIndex];
239 accumulator [decPointIndex] = 0;
240 exponentAccumulator [decPointIndex] = 0;
243 accumulator [decPointIndex] = accumulator[decPointIndex] * 10 + digit;
244 exponentAccumulator [decPointIndex]++;
247 else if (decPointIndex == 0 && *text ==
'.')
252 if (numSignificantDigits > maxSignificantDigits)
254 while (text.isDigit())
265 result[0] = mulexp10 (result[0], exponentAccumulator[0]) + accumulator[0];
267 if (decPointIndex != 0)
268 result[1] = mulexp10 (result[1], exponentAccumulator[1]) + accumulator[1];
271 if ((c ==
'e' || c ==
'E') && digitsFound)
273 auto negativeExponent =
false;
277 case '-': negativeExponent =
true;
281 while (text.isDigit())
282 exponent = (exponent * 10) + ((
int) text.getAndAdvance() -
'0');
284 if (negativeExponent)
285 exponent = -exponent;
288 auto r = mulexp10 (result[0], exponent + exponentAdjustment[0]);
289 if (decPointIndex != 0)
290 r += mulexp10 (result[1], exponent - exponentAdjustment[1]);
292 return isNegative ? -r : r;
297 bool decimalPointFound =
false;
298 int extraExponent = 0;
304 auto digit = (int) text.getAndAdvance() -
'0';
306 if (decimalPointFound)
308 if (numSigFigs >= maxSignificantDigits)
313 if (numSigFigs >= maxSignificantDigits)
319 if (numSigFigs == 0 && digit == 0)
323 *currentCharacter++ = (char) (
'0' + (
char) digit);
326 else if ((! decimalPointFound) && *text ==
'.')
329 *currentCharacter++ =
'.';
330 decimalPointFound =
true;
340 auto writeExponentDigits = [](
int exponent,
char* destination)
342 auto exponentDivisor = 100;
344 while (exponentDivisor > 1)
346 auto digit = exponent / exponentDivisor;
347 *destination++ = (char) (
'0' + (
char) digit);
348 exponent -= digit * exponentDivisor;
349 exponentDivisor /= 10;
352 *destination++ = (char) (
'0' + (
char) exponent);
355 if ((c ==
'e' || c ==
'E') && numSigFigs > 0)
357 *currentCharacter++ =
'e';
358 bool parsedExponentIsPositive =
true;
362 case '-': parsedExponentIsPositive =
false;
368 while (text.isDigit())
370 auto digit = (int) text.getAndAdvance() -
'0';
372 if (digit != 0 || exponent != 0)
373 exponent = (exponent * 10) + digit;
376 exponent = extraExponent + (parsedExponentIsPositive ? exponent : -exponent);
379 *currentCharacter++ =
'-';
381 exponent = std::abs (exponent);
383 if (exponent > std::numeric_limits<double>::max_exponent10)
384 return std::numeric_limits<double>::quiet_NaN();
386 writeExponentDigits (exponent, currentCharacter);
388 else if (extraExponent > 0)
390 *currentCharacter++ =
'e';
391 writeExponentDigits (extraExponent, currentCharacter);
395 static _locale_t locale = _create_locale (LC_ALL,
"C");
396 return _strtod_l (&buffer[0],
nullptr, locale);
398 static locale_t locale = newlocale (LC_ALL_MASK,
"C",
nullptr);
400 return (
double) strtold_l (&buffer[0],
nullptr, locale);
402 return strtod_l (&buffer[0],
nullptr, locale);