41 constexpr
int kDecimalMantissaDigitsMax = 19;
43 static_assert(std::numeric_limits<uint64_t>::digits10 ==
44 kDecimalMantissaDigitsMax,
48 static_assert(std::numeric_limits<double>::is_iec559,
"IEEE double assumed");
50 static_assert(std::numeric_limits<double>::digits == 53,
"IEEE double fact");
54 static_assert(1000000000000000000u > (uint64_t(1) << (53 + 3)),
"(b) above");
67 constexpr
int kHexadecimalMantissaDigitsMax = 15;
73 constexpr
int kGuaranteedHexadecimalMantissaBitPrecision =
74 4 * kHexadecimalMantissaDigitsMax - 3;
76 static_assert(kGuaranteedHexadecimalMantissaBitPrecision >
77 std::numeric_limits<double>::digits + 2,
78 "kHexadecimalMantissaDigitsMax too small");
88 constexpr
int kDecimalExponentDigitsMax = 9;
89 static_assert(std::numeric_limits<int>::digits10 >= kDecimalExponentDigitsMax,
90 "int type too small");
96 constexpr
int kDecimalDigitLimit = 50000000;
101 constexpr
int kHexadecimalDigitLimit = kDecimalDigitLimit / 4;
112 static_assert(999999999 + 2 * kDecimalDigitLimit <
113 std::numeric_limits<int>::max(),
114 "int type too small");
115 static_assert(999999999 + 2 * (4 * kHexadecimalDigitLimit) <
116 std::numeric_limits<int>::max(),
117 "int type too small");
125 return scientific || !fixed;
133 return scientific && !fixed;
136 const int8_t kAsciiToInt[256] = {
137 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
138 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
139 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8,
140 9, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1,
141 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
142 -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
143 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
144 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
145 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
146 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
147 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
148 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
149 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
150 -1, -1, -1, -1, -1, -1, -1, -1, -1};
158 unsigned ToDigit(
char ch);
162 bool IsExponentCharacter(
char ch);
167 constexpr
int MantissaDigitsMax();
172 constexpr
int DigitLimit();
179 constexpr
int DigitMagnitude();
182 bool IsDigit<10>(
char ch) {
183 return ch >=
'0' && ch <=
'9';
186 bool IsDigit<16>(
char ch) {
187 return kAsciiToInt[
static_cast<unsigned char>(ch)] >= 0;
191 unsigned ToDigit<10>(
char ch) {
195 unsigned ToDigit<16>(
char ch) {
196 return kAsciiToInt[
static_cast<unsigned char>(ch)];
200 bool IsExponentCharacter<10>(
char ch) {
201 return ch ==
'e' || ch ==
'E';
205 bool IsExponentCharacter<16>(
char ch) {
206 return ch ==
'p' || ch ==
'P';
210 constexpr
int MantissaDigitsMax<10>() {
211 return kDecimalMantissaDigitsMax;
214 constexpr
int MantissaDigitsMax<16>() {
215 return kHexadecimalMantissaDigitsMax;
219 constexpr
int DigitLimit<10>() {
220 return kDecimalDigitLimit;
223 constexpr
int DigitLimit<16>() {
224 return kHexadecimalDigitLimit;
228 constexpr
int DigitMagnitude<10>() {
232 constexpr
int DigitMagnitude<16>() {
247 template <
int base,
typename T>
248 std::size_t ConsumeDigits(
const char*
begin,
const char*
end,
int max_digits,
249 T*
out,
bool* dropped_nonzero_digit) {
251 assert(max_digits <= std::numeric_limits<T>::digits10);
252 }
else if (base == 16) {
253 assert(max_digits * 4 <= std::numeric_limits<T>::digits);
255 const char*
const original_begin =
begin;
256 T accumulator = *
out;
257 const char* significant_digits_end =
258 (end - begin > max_digits) ? begin + max_digits : end;
259 while (begin < significant_digits_end && IsDigit<base>(*begin)) {
262 auto digit =
static_cast<T
>(ToDigit<base>(*begin));
263 assert(accumulator * base >= accumulator);
265 assert(accumulator + digit >= accumulator);
266 accumulator += digit;
269 bool dropped_nonzero =
false;
270 while (begin < end && IsDigit<base>(*begin)) {
271 dropped_nonzero = dropped_nonzero || (*begin !=
'0');
274 if (dropped_nonzero && dropped_nonzero_digit !=
nullptr) {
275 *dropped_nonzero_digit =
true;
278 return begin - original_begin;
283 bool IsNanChar(
char v) {
284 return (v ==
'_') || (v >=
'0' && v <= '9') || (v >=
'a' && v <=
'z') ||
285 (v >=
'A' && v <=
'Z');
290 bool ParseInfinityOrNan(
const char* begin,
const char* end,
291 strings_internal::ParsedFloat* out) {
292 if (end - begin < 3) {
304 if (end - begin >= 8 &&
306 out->end = begin + 8;
308 out->end = begin + 3;
321 out->end = begin + 3;
325 if (begin < end && *begin ==
'(') {
326 const char* nan_begin = begin + 1;
327 while (nan_begin < end && IsNanChar(*nan_begin)) {
330 if (nan_begin < end && *nan_begin ==
')') {
332 out->subrange_begin = begin + 1;
333 out->subrange_end = nan_begin;
334 out->end = nan_begin + 1;
345 namespace strings_internal {
353 if (begin == end)
return result;
356 if (ParseInfinityOrNan(begin, end, &result)) {
360 const char*
const mantissa_begin =
begin;
361 while (begin < end && *begin ==
'0') {
366 int exponent_adjustment = 0;
367 bool mantissa_is_inexact =
false;
368 std::size_t pre_decimal_digits = ConsumeDigits<base>(
369 begin,
end, MantissaDigitsMax<base>(), &mantissa, &mantissa_is_inexact);
370 begin += pre_decimal_digits;
372 if (pre_decimal_digits >= DigitLimit<base>()) {
375 }
else if (pre_decimal_digits > MantissaDigitsMax<base>()) {
378 exponent_adjustment =
379 static_cast<int>(pre_decimal_digits - MantissaDigitsMax<base>());
383 static_cast<int>(MantissaDigitsMax<base>() - pre_decimal_digits);
385 if (begin < end && *begin ==
'.') {
390 const char* begin_zeros =
begin;
391 while (begin < end && *begin ==
'0') {
394 std::size_t zeros_skipped = begin - begin_zeros;
395 if (zeros_skipped >= DigitLimit<base>()) {
399 exponent_adjustment -=
static_cast<int>(zeros_skipped);
401 std::size_t post_decimal_digits = ConsumeDigits<base>(
403 begin += post_decimal_digits;
409 if (post_decimal_digits >= DigitLimit<base>()) {
412 }
else if (post_decimal_digits > digits_left) {
413 exponent_adjustment -= digits_left;
415 exponent_adjustment -= post_decimal_digits;
419 if (mantissa_begin == begin) {
423 if (begin - mantissa_begin == 1 && *mantissa_begin ==
'.') {
427 if (mantissa_is_inexact) {
434 }
else if (base == 16) {
442 const char*
const exponent_begin =
begin;
444 bool found_exponent =
false;
445 if (AllowExponent(format_flags) && begin < end &&
446 IsExponentCharacter<base>(*begin)) {
447 bool negative_exponent =
false;
449 if (begin < end && *begin ==
'-') {
450 negative_exponent =
true;
452 }
else if (begin < end && *begin ==
'+') {
455 const char*
const exponent_digits_begin =
begin;
457 begin += ConsumeDigits<10>(
begin,
end, kDecimalExponentDigitsMax,
459 if (begin == exponent_digits_begin) {
462 found_exponent =
false;
463 begin = exponent_begin;
465 found_exponent =
true;
466 if (negative_exponent) {
472 if (!found_exponent && RequireExponent(format_flags)) {
482 (DigitMagnitude<base>() * exponent_adjustment);
const char * subrange_begin
template ParsedFloat ParseFloat< 10 >(const char *begin, const char *end, chars_format format_flags)
const char * subrange_end
template ParsedFloat ParseFloat< 16 >(const char *begin, const char *end, chars_format format_flags)
static bool IsDigit(char c)
strings_internal::ParsedFloat ParseFloat(const char *begin, const char *end, chars_format format_flags)
int memcasecmp(const char *s1, const char *s2, size_t len)