264 auto fail = [&]() -> u32 {
265 if (consumed) *consumed = 0;
270 while (i < len && (s[i] ==
' ' || s[i] ==
'\t' || s[i] ==
'\n' ||
271 s[i] ==
'\r' || s[i] ==
'\f' || s[i] ==
'\v')) {
277 if (i < len && s[i] ==
'-') { sign_bit = kSignBitMask; ++i; }
278 else if (i < len && s[i] ==
'+') { ++i; }
286 int significant_digits = 0;
287 bool seen_decimal =
false;
288 bool seen_digit =
false;
289 constexpr int kMaxSignificantDigits = 19;
293 if (c >=
'0' && c <=
'9') {
295 if (significant_digits < kMaxSignificantDigits) {
297 mantissa = mantissa * 10u +
static_cast<fl::u64>(c -
'0');
298 if (significant_digits != 0 || c !=
'0') {
299 ++significant_digits;
311 }
else if (c ==
'.' && !seen_decimal) {
327 if (i < len && (s[i] ==
'e' || s[i] ==
'E')) {
328 const fl::size exp_start = i + 1;
329 fl::size j = exp_start;
331 if (j < len && s[j] ==
'-') { exp_sign = -1; ++j; }
332 else if (j < len && s[j] ==
'+') { ++j; }
334 const fl::size digits_begin = j;
335 while (j < len && s[j] >=
'0' && s[j] <=
'9') {
336 if (exp_val < 10000) {
337 exp_val = exp_val * 10 + (s[j] -
'0');
341 if (j != digits_begin) {
342 decimal_exp += exp_sign * exp_val;
348 if (consumed) *consumed = i;
356 int mantissa_shift = 0;
357 while ((mantissa & 0x8000000000000000ull) == 0) {
367 if (decimal_exp < kPow10KMin) {
370 if (decimal_exp > kPow10KMax) {
371 return sign_bit | kInfBitsPos;
374 const fl::size idx =
static_cast<fl::size
>(decimal_exp - kPow10KMin);
375 const fl::u64 pow_mant = kPow10Mant[idx];
376 const int pow_exp = kPow10BExp[idx];
378 fl::u64 product_hi = mul_hi_u64(mantissa, pow_mant);
383 if ((product_hi & 0x8000000000000000ull) == 0) {
391 int bin_exp = -mantissa_shift + pow_exp + 64 - extra_shift;
395 int biased_exp = bin_exp + 63 + 127;
397 if (biased_exp >= 0xFF) {
398 return sign_bit | kInfBitsPos;
400 if (biased_exp <= 0) {
411 fl::u32 ieee_mant =
static_cast<fl::u32
>((product_hi >> 40) & 0x7FFFFFu);
412 const fl::u64 round_bit = (product_hi >> 39) & 1u;
413 const fl::u64 sticky = (product_hi & 0x7FFFFFFFFFull);
414 if (round_bit && (sticky != 0 || (ieee_mant & 1u))) {
416 if (ieee_mant == (1u << 23)) {
420 if (biased_exp >= 0xFF) {
421 return sign_bit | kInfBitsPos;
426 return sign_bit | (
static_cast<fl::u32
>(biased_exp) << 23) | ieee_mant;
440 if (precision < 0) precision = 0;
441 if (precision > 9) precision = 9;
443 const bool neg = (bits >> 31) & 1u;
444 const int biased_exp =
static_cast<int>((bits >> 23) & 0xFFu);
445 const u32 mant_bits = bits & 0x7FFFFFu;
448 if (biased_exp == 0xFF) {
455 auto append_zero_with_precision = [&]() {
459 for (
int i = 0; i < precision; ++i) s +=
"0";
465 if (biased_exp == 0) {
467 append_zero_with_precision();
473 const u32 mantissa_full = mant_bits | 0x800000u;
474 const int bin_exp_raw = biased_exp - 127 - 23;
479 const u64 mant64 =
static_cast<u64>(mantissa_full) << 40;
480 const int bin_exp = bin_exp_raw - 40;
483 const fl::size idx =
static_cast<fl::size
>(precision - kPow10KMin);
484 const u64 pow_mant = kPow10Mant[idx];
485 const int pow_exp = kPow10BExp[idx];
488 u64 scaled_hi = mul_hi_u64(mant64, pow_mant);
489 int scaled_bin_exp = bin_exp + pow_exp + 64;
490 if ((scaled_hi & 0x8000000000000000ull) == 0) {
500 if (scaled_bin_exp >= 0) {
501 if (scaled_bin_exp > 0) {
506 scaled_int = scaled_hi;
508 const int shift = -scaled_bin_exp;
513 const u64 mask = (shift == 64) ? ~0ull : ((1ull << shift) - 1ull);
514 const u64 low = scaled_hi & mask;
515 scaled_int = scaled_hi >> shift;
516 const u64 half = (shift == 0) ? 0 : (1ull << (shift - 1));
517 if (low > half || (low == half && (scaled_int & 1ull))) {
526 static constexpr u32 kPow10IntExact[] = {
527 1u, 10u, 100u, 1000u,
528 10000u, 100000u, 1000000u, 10000000u,
529 100000000u, 1000000000u,
531 const u64 pow10_exact = kPow10IntExact[precision];
533 const u64 int_part = scaled_int / pow10_exact;
534 const u64 frac_part = scaled_int % pow10_exact;
536 if (neg && (int_part != 0 || frac_part != 0)) {
548 for (
int i = n; i < precision; ++i) s +=
"0";
549 for (
int i = 0; i < n; ++i) s +=
fl::string(1, buf[i]);