46 if (!str.
empty() && str[0] ==
'+') {
50 if (result.ec == std::errc::invalid_argument) {
53 if (result.ptr != str.
data() + str.
size()) {
59 if (result.ec == std::errc::result_out_of_range) {
61 *out = std::numeric_limits<float>::infinity();
62 }
else if (*out < -1.0) {
63 *out = -std::numeric_limits<float>::infinity();
72 if (!str.
empty() && str[0] ==
'+') {
76 if (result.ec == std::errc::invalid_argument) {
79 if (result.ptr != str.
data() + str.
size()) {
85 if (result.ec == std::errc::result_out_of_range) {
87 *out = std::numeric_limits<double>::infinity();
88 }
else if (*out < -1.0) {
89 *out = -std::numeric_limits<double>::infinity();
103 inline void PutTwoDigits(
size_t i,
char*
buf) {
104 static const char two_ASCII_digits[100][2] = {
105 {
'0',
'0'}, {
'0',
'1'}, {
'0',
'2'}, {
'0',
'3'}, {
'0',
'4'},
106 {
'0',
'5'}, {
'0',
'6'}, {
'0',
'7'}, {
'0',
'8'}, {
'0',
'9'},
107 {
'1',
'0'}, {
'1',
'1'}, {
'1',
'2'}, {
'1',
'3'}, {
'1',
'4'},
108 {
'1',
'5'}, {
'1',
'6'}, {
'1',
'7'}, {
'1',
'8'}, {
'1',
'9'},
109 {
'2',
'0'}, {
'2',
'1'}, {
'2',
'2'}, {
'2',
'3'}, {
'2',
'4'},
110 {
'2',
'5'}, {
'2',
'6'}, {
'2',
'7'}, {
'2',
'8'}, {
'2',
'9'},
111 {
'3',
'0'}, {
'3',
'1'}, {
'3',
'2'}, {
'3',
'3'}, {
'3',
'4'},
112 {
'3',
'5'}, {
'3',
'6'}, {
'3',
'7'}, {
'3',
'8'}, {
'3',
'9'},
113 {
'4',
'0'}, {
'4',
'1'}, {
'4',
'2'}, {
'4',
'3'}, {
'4',
'4'},
114 {
'4',
'5'}, {
'4',
'6'}, {
'4',
'7'}, {
'4',
'8'}, {
'4',
'9'},
115 {
'5',
'0'}, {
'5',
'1'}, {
'5',
'2'}, {
'5',
'3'}, {
'5',
'4'},
116 {
'5',
'5'}, {
'5',
'6'}, {
'5',
'7'}, {
'5',
'8'}, {
'5',
'9'},
117 {
'6',
'0'}, {
'6',
'1'}, {
'6',
'2'}, {
'6',
'3'}, {
'6',
'4'},
118 {
'6',
'5'}, {
'6',
'6'}, {
'6',
'7'}, {
'6',
'8'}, {
'6',
'9'},
119 {
'7',
'0'}, {
'7',
'1'}, {
'7',
'2'}, {
'7',
'3'}, {
'7',
'4'},
120 {
'7',
'5'}, {
'7',
'6'}, {
'7',
'7'}, {
'7',
'8'}, {
'7',
'9'},
121 {
'8',
'0'}, {
'8',
'1'}, {
'8',
'2'}, {
'8',
'3'}, {
'8',
'4'},
122 {
'8',
'5'}, {
'8',
'6'}, {
'8',
'7'}, {
'8',
'8'}, {
'8',
'9'},
123 {
'9',
'0'}, {
'9',
'1'}, {
'9',
'2'}, {
'9',
'3'}, {
'9',
'4'},
124 {
'9',
'5'}, {
'9',
'6'}, {
'9',
'7'}, {
'9',
'8'}, {
'9',
'9'}
127 memcpy(buf, two_ASCII_digits[i], 2);
133 ABSL_RAW_CHECK(out !=
nullptr,
"Output pointer must not be nullptr.");
164 const char one_ASCII_final_digits[10][2] {
165 {
'0', 0}, {
'1', 0}, {
'2', 0}, {
'3', 0}, {
'4', 0},
166 {
'5', 0}, {
'6', 0}, {
'7', 0}, {
'8', 0}, {
'9', 0},
179 if (i >= 1000000000) {
180 digits = i / 100000000;
181 i -= digits * 100000000;
182 PutTwoDigits(digits, buffer);
185 digits = i / 1000000;
186 i -= digits * 1000000;
187 PutTwoDigits(digits, buffer);
192 PutTwoDigits(digits, buffer);
197 PutTwoDigits(digits, buffer);
201 PutTwoDigits(digits, buffer);
209 if (i >= 10)
goto lt100;
210 memcpy(buffer, one_ASCII_final_digits[i], 2);
214 if (i >= 1000)
goto lt10_000;
217 *buffer++ =
'0' + digits;
221 if (i >= 100000)
goto lt1_000_000;
224 *buffer++ =
'0' + digits;
228 if (i >= 10000000)
goto lt100_000_000;
229 digits = i / 1000000;
230 i -= digits * 1000000;
231 *buffer++ =
'0' + digits;
235 digits = i / 100000000;
236 i -= digits * 100000000;
237 *buffer++ =
'0' + digits;
254 uint32_t u32 =
static_cast<uint32_t
>(
i);
258 uint64_t top_1to11 = i / 1000000000;
259 u32 =
static_cast<uint32_t
>(i - top_1to11 * 1000000000);
260 uint32_t top_1to11_32 =
static_cast<uint32_t
>(top_1to11);
262 if (top_1to11_32 == top_1to11) {
266 uint32_t top_8to9 =
static_cast<uint32_t
>(top_1to11 / 100);
267 uint32_t mid_2 =
static_cast<uint32_t
>(top_1to11 - top_8to9 * 100);
269 PutTwoDigits(mid_2, buffer);
274 uint32_t digits = u32 / 10000000;
275 u32 -= digits * 10000000;
276 PutTwoDigits(digits, buffer);
278 digits = u32 / 100000;
279 u32 -= digits * 100000;
280 PutTwoDigits(digits, buffer);
283 u32 -= digits * 1000;
284 PutTwoDigits(digits, buffer);
288 PutTwoDigits(digits, buffer);
290 memcpy(buffer, one_ASCII_final_digits[u32], 2);
306 static std::pair<uint64_t, uint64_t>
Mul32(std::pair<uint64_t, uint64_t> num,
308 uint64_t bits0_31 = num.second & 0xFFFFFFFF;
309 uint64_t bits32_63 = num.second >> 32;
310 uint64_t bits64_95 = num.first & 0xFFFFFFFF;
311 uint64_t bits96_127 = num.first >> 32;
334 uint64_t bits0_63 = bits0_31 + (bits32_63 << 32);
335 uint64_t bits64_127 = bits64_95 + (bits96_127 << 32) + (bits32_63 >> 32) +
336 (bits0_63 < bits0_31);
337 uint64_t bits128_up = (bits96_127 >> 32) + (bits64_127 < bits64_95);
338 if (bits128_up == 0)
return {bits64_127, bits0_63};
341 uint64_t lo = (bits0_63 >> shift) + (bits64_127 << (64 - shift));
342 uint64_t hi = (bits64_127 >> shift) + (bits128_up << (64 - shift));
349 static std::pair<uint64_t, uint64_t>
PowFive(uint64_t num,
int expfive) {
350 std::pair<uint64_t, uint64_t> result = {num, 0};
351 while (expfive >= 13) {
353 result =
Mul32(result, 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5);
356 constexpr
int powers_of_five[13] = {
363 5 * 5 * 5 * 5 * 5 * 5,
364 5 * 5 * 5 * 5 * 5 * 5 * 5,
365 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
366 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
367 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
368 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
369 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5};
370 result =
Mul32(result, powers_of_five[expfive & 15]);
373 result.first = (result.first << shift) + (result.second >> (64 - shift));
374 result.second = (result.second << shift);
401 if (d >= 1e+261) exp += 256, d *= 1e-256;
402 if (d >= 1e+133) exp += 128, d *= 1e-128;
403 if (d >= 1e+69) exp += 64, d *= 1e-64;
404 if (d >= 1e+37) exp += 32, d *= 1e-32;
405 if (d >= 1e+21) exp += 16, d *= 1e-16;
406 if (d >= 1e+13) exp += 8, d *= 1e-8;
407 if (d >= 1e+9) exp += 4, d *= 1e-4;
408 if (d >= 1e+7) exp += 2, d *= 1e-2;
409 if (d >= 1e+6) exp += 1, d *= 1e-1;
411 if (d < 1e-250) exp -= 256, d *= 1e256;
412 if (d < 1e-122) exp -= 128, d *= 1e128;
413 if (d < 1e-58) exp -= 64, d *= 1e64;
414 if (d < 1e-26) exp -= 32, d *= 1e32;
415 if (d < 1e-10) exp -= 16, d *= 1e16;
416 if (d < 1e-2) exp -= 8, d *= 1e8;
417 if (d < 1e+2) exp -= 4, d *= 1e4;
418 if (d < 1e+4) exp -= 2, d *= 1e2;
419 if (d < 1e+5) exp -= 1, d *= 1e1;
430 uint64_t d64k = d * 65536;
432 if ((d64k % 65536) == 32767 || (d64k % 65536) == 32768) {
438 dddddd =
static_cast<int>(d64k / 65536);
443 double m = std::frexp(value, &exp2);
444 uint64_t
mantissa = m * (32768.0 * 65536.0 * 65536.0 * 65536.0);
462 std::pair<uint64_t, uint64_t> edge, val;
467 edge =
PowFive(2 * dddddd + 1, exp - 5);
475 edge =
PowFive(2 * dddddd + 1, 0);
477 val =
PowFive(mantissa, 5 - exp);
483 }
else if (val == edge) {
484 dddddd += (dddddd & 1);
488 dddddd =
static_cast<int>((d64k + 32768) / 65536);
490 if (dddddd == 1000000) {
496 int two_digits = dddddd / 10000;
497 dddddd -= two_digits * 10000;
498 PutTwoDigits(two_digits, &exp_dig.
digits[0]);
500 two_digits = dddddd / 100;
501 dddddd -= two_digits * 100;
502 PutTwoDigits(two_digits, &exp_dig.
digits[2]);
504 PutTwoDigits(dddddd, &exp_dig.
digits[4]);
511 static_assert(std::numeric_limits<float>::is_iec559,
512 "IEEE-754/IEC-559 support only");
523 if (std::signbit(d)) *out++ =
'-';
534 return out + 3 - buffer;
538 int exp = exp_dig.exponent;
539 const char*
digits = exp_dig.digits;
544 memcpy(out, &digits[0], 6), out += 6;
548 memcpy(out, &digits[0], 5), out += 5;
549 if (digits[5] !=
'0') {
556 memcpy(out, &digits[0], 4), out += 4;
557 if ((digits[5] | digits[4]) !=
'0') {
560 if (digits[5] !=
'0') *out++ = digits[5];
565 memcpy(out, &digits[0], 3), out += 3;
567 memcpy(out, &digits[3], 3);
569 while (out[-1] ==
'0') --
out;
570 if (out[-1] ==
'.') --
out;
574 memcpy(out, &digits[0], 2), out += 2;
576 memcpy(out, &digits[2], 4);
578 while (out[-1] ==
'0') --
out;
579 if (out[-1] ==
'.') --
out;
583 memcpy(out, &digits[0], 1), out += 1;
585 memcpy(out, &digits[1], 5);
587 while (out[-1] ==
'0') --
out;
588 if (out[-1] ==
'.') --
out;
605 memcpy(out, &digits[0], 6);
607 while (out[-1] ==
'0') --
out;
611 assert(exp < -4 || exp >= 6);
613 assert(out[1] ==
'.');
615 memcpy(out, &digits[1], 5), out += 5;
616 while (out[-1] ==
'0') --
out;
617 if (out[-1] ==
'.') --
out;
626 int dig1 = exp / 100;
630 PutTwoDigits(exp, out);
640 static const int8_t kAsciiToInt[256] = {
641 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
642 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
643 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 0, 1, 2, 3, 4, 5,
644 6, 7, 8, 9, 36, 36, 36, 36, 36, 36, 36, 10, 11, 12, 13, 14, 15, 16, 17,
645 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
646 36, 36, 36, 36, 36, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
647 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36, 36, 36, 36, 36,
648 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
649 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
650 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
651 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
652 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
653 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
654 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36};
659 bool* negative_ptr ) {
660 if (text->
data() ==
nullptr) {
664 const char* start = text->
data();
665 const char*
end = start + text->
size();
666 int base = *base_ptr;
680 *negative_ptr = (start[0] ==
'-');
681 if (*negative_ptr || start[0] ==
'+') {
693 if (end - start >= 2 && start[0] ==
'0' &&
694 (start[1] ==
'x' || start[1] ==
'X')) {
701 }
else if (end - start >= 1 && start[0] ==
'0') {
707 }
else if (base == 16) {
708 if (end - start >= 2 && start[0] ==
'0' &&
709 (start[1] ==
'x' || start[1] ==
'X')) {
716 }
else if (base >= 2 && base <= 36) {
755 template <
typename IntType>
756 struct LookupTables {
764 #define X_OVER_BASE_INITIALIZER(X) \ 766 0, 0, X / 2, X / 3, X / 4, X / 5, X / 6, X / 7, X / 8, X / 9, X / 10, \ 767 X / 11, X / 12, X / 13, X / 14, X / 15, X / 16, X / 17, X / 18, \ 768 X / 19, X / 20, X / 21, X / 22, X / 23, X / 24, X / 25, X / 26, \ 769 X / 27, X / 28, X / 29, X / 30, X / 31, X / 32, X / 33, X / 34, \ 773 template <
typename IntType>
777 template <
typename IntType>
781 #undef X_OVER_BASE_INITIALIZER 783 template <
typename IntType>
787 const IntType vmax = std::numeric_limits<IntType>::max();
790 assert(vmax >= static_cast<IntType>(base));
791 const IntType vmax_over_base = LookupTables<IntType>::kVmaxOverBase[base];
792 const char* start = text.
data();
793 const char*
end = start + text.
size();
795 for (; start <
end; ++start) {
796 unsigned char c =
static_cast<unsigned char>(start[0]);
797 int digit = kAsciiToInt[c];
802 if (value > vmax_over_base) {
807 if (value > vmax - digit) {
817 template <
typename IntType>
821 const IntType vmin = std::numeric_limits<IntType>::min();
823 assert(vmin <= 0 - base);
824 IntType vmin_over_base = LookupTables<IntType>::kVminOverBase[base];
830 if (vmin % base > 0) {
833 const char* start = text.
data();
834 const char* end = start + text.
size();
836 for (; start <
end; ++start) {
837 unsigned char c =
static_cast<unsigned char>(start[0]);
838 int digit = kAsciiToInt[c];
843 if (value < vmin_over_base) {
848 if (value < vmin + digit) {
860 template <
typename IntType>
865 if (!safe_parse_sign_and_base(&text, &base, &negative)) {
869 return safe_parse_positive_int(text, base, value_p);
871 return safe_parse_negative_int(text, base, value_p);
875 template <
typename IntType>
880 if (!safe_parse_sign_and_base(&text, &base, &negative) || negative) {
883 return safe_parse_positive_int(text, base, value_p);
887 namespace numbers_internal {
889 return safe_int_internal<int32_t>(text,
value, base);
893 return safe_int_internal<int64_t>(text,
value, base);
897 return safe_uint_internal<uint32_t>(text,
value, base);
901 return safe_uint_internal<uint64_t>(text,
value, base);
bool safe_strtou64_base(absl::string_view text, uint64_t *value, int base)
char * FastIntToBuffer(int32_t, char *)
void remove_prefix(size_type n)
static const IntType kVminOverBase[]
static const IntType kVmaxOverBase[]
size_t SixDigitsToBuffer(double d, char *buffer)
bool ascii_isspace(unsigned char c)
ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64(uint64_t n)
static std::pair< uint64_t, uint64_t > PowFive(uint64_t num, int expfive)
bool safe_strtou32_base(absl::string_view text, uint32_t *value, int base)
constexpr size_type size() const noexcept
bool SimpleAtod(absl::string_view str, double *out)
bool SimpleAtof(absl::string_view str, float *out)
bool safe_strto32_base(absl::string_view text, int32_t *value, int base)
#define ABSL_RAW_CHECK(condition, message)
#define ABSL_FALLTHROUGH_INTENDED
static ExpDigits SplitToSix(const double value)
ABSL_MUST_USE_RESULT absl::string_view StripAsciiWhitespace(absl::string_view str)
constexpr bool empty() const noexcept
bool safe_strto64_base(absl::string_view text, int64_t *value, int base)
static std::pair< uint64_t, uint64_t > Mul32(std::pair< uint64_t, uint64_t > num, uint32_t mul)
from_chars_result from_chars(const char *first, const char *last, double &value, chars_format fmt)
constexpr const_pointer data() const noexcept
#define X_OVER_BASE_INITIALIZER(X)
bool EqualsIgnoreCase(absl::string_view piece1, absl::string_view piece2)
bool SimpleAtob(absl::string_view str, bool *out)