Fix hpd__small_rshift clobbering the negative bit

Also link to the Simple Decimal Conversion blog post.
diff --git a/internal/cgen/base/floatconv-submodule-code.c b/internal/cgen/base/floatconv-submodule-code.c
index 3b116d9..a7ad93e 100644
--- a/internal/cgen/base/floatconv-submodule-code.c
+++ b/internal/cgen/base/floatconv-submodule-code.c
@@ -680,7 +680,6 @@
     // After the shift, h's number is effectively zero.
     h->num_digits = 0;
     h->decimal_point = 0;
-    h->negative = false;
     h->truncated = false;
     return;
   }
@@ -1307,6 +1306,9 @@
       }
     }
 
+    // When Eisel-Lemire fails, fall back to Simple Decimal Conversion. See
+    // https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html
+    //
     // Scale by powers of 2 until we're in the range [½ .. 1], which gives us
     // our exponent (in base-2). First we shift right, possibly a little too
     // far, ending with a value certainly below 1 and possibly below ½...
diff --git a/internal/cgen/data/data.go b/internal/cgen/data/data.go
index 19266fe..2373417 100644
--- a/internal/cgen/data/data.go
+++ b/internal/cgen/data/data.go
@@ -369,9 +369,9 @@
 	"INT64_MAX;\n  }\n\n  uint32_t dp = (uint32_t)(h->decimal_point);\n  uint64_t n = 0;\n  uint32_t i = 0;\n  for (; i < dp; i++) {\n    n = (10 * n) + ((i < h->num_digits) ? h->digits[i] : 0);\n  }\n\n  bool round_up = false;\n  if (dp < h->num_digits) {\n    round_up = h->digits[dp] >= 5;\n    if ((h->digits[dp] == 5) && (dp + 1 == h->num_digits)) {\n      // We are exactly halfway. If we're truncated, round up, otherwise round\n      // to even.\n      round_up = h->truncated ||  //\n                 ((dp > 0) && (1 & h->digits[dp - 1]));\n    }\n  }\n  if (round_up) {\n    n++;\n  }\n\n  return n;\n}\n\n// wuffs_base__private_implementation__high_prec_dec__small_xshift shifts h's\n// number (where 'x' is 'l' or 'r' for left or right) by a small shift value.\n//\n// Preconditions:\n//  - h is non-NULL.\n//  - h->decimal_point is \"not extreme\".\n//  - shift is non-zero.\n//  - shift is \"a small shift\".\n//\n// \"Not extreme\" means within\n// ±WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.\n//\n// \"A small shift\" means not more than\n/" +
 	"/ WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.\n//\n// wuffs_base__private_implementation__high_prec_dec__rounded_integer and\n// wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits\n// have the same preconditions.\n//\n// wuffs_base__private_implementation__high_prec_dec__lshift keeps the first\n// two preconditions but not the last two. Its shift argument is signed and\n// does not need to be \"small\": zero is a no-op, positive means left shift and\n// negative means right shift.\n\nstatic void  //\nwuffs_base__private_implementation__high_prec_dec__small_lshift(\n    wuffs_base__private_implementation__high_prec_dec* h,\n    uint32_t shift) {\n  if (h->num_digits == 0) {\n    return;\n  }\n  uint32_t num_new_digits =\n      wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits(\n          h, shift);\n  uint32_t rx = h->num_digits - 1;                   // Read  index.\n  uint32_t wx = h->num_digits - 1 + num_new_digits;  // Write index.\n  uint64_t n = 0;\n\n  // Repeat: pick up " +
 	"a digit, put down a digit, right to left.\n  while (((int32_t)rx) >= 0) {\n    n += ((uint64_t)(h->digits[rx])) << shift;\n    uint64_t quo = n / 10;\n    uint64_t rem = n - (10 * quo);\n    if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {\n      h->digits[wx] = (uint8_t)rem;\n    } else if (rem > 0) {\n      h->truncated = true;\n    }\n    n = quo;\n    wx--;\n    rx--;\n  }\n\n  // Put down leading digits, right to left.\n  while (n > 0) {\n    uint64_t quo = n / 10;\n    uint64_t rem = n - (10 * quo);\n    if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {\n      h->digits[wx] = (uint8_t)rem;\n    } else if (rem > 0) {\n      h->truncated = true;\n    }\n    n = quo;\n    wx--;\n  }\n\n  // Finish.\n  h->num_digits += num_new_digits;\n  if (h->num_digits >\n      WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {\n    h->num_digits = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION;\n  }\n  h->decimal_point += (int32_t)num_new_digits;\n  wuffs_base__private_implementation__high_pre" +
-	"c_dec__trim(h);\n}\n\nstatic void  //\nwuffs_base__private_implementation__high_prec_dec__small_rshift(\n    wuffs_base__private_implementation__high_prec_dec* h,\n    uint32_t shift) {\n  uint32_t rx = 0;  // Read  index.\n  uint32_t wx = 0;  // Write index.\n  uint64_t n = 0;\n\n  // Pick up enough leading digits to cover the first shift.\n  while ((n >> shift) == 0) {\n    if (rx < h->num_digits) {\n      // Read a digit.\n      n = (10 * n) + h->digits[rx++];\n    } else if (n == 0) {\n      // h's number used to be zero and remains zero.\n      return;\n    } else {\n      // Read sufficient implicit trailing zeroes.\n      while ((n >> shift) == 0) {\n        n = 10 * n;\n        rx++;\n      }\n      break;\n    }\n  }\n  h->decimal_point -= ((int32_t)(rx - 1));\n  if (h->decimal_point <\n      -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {\n    // After the shift, h's number is effectively zero.\n    h->num_digits = 0;\n    h->decimal_point = 0;\n    h->negative = false;\n    h->truncated = false;\n    return;\n  }\n\n  " +
-	"// Repeat: pick up a digit, put down a digit, left to right.\n  uint64_t mask = (((uint64_t)(1)) << shift) - 1;\n  while (rx < h->num_digits) {\n    uint8_t new_digit = ((uint8_t)(n >> shift));\n    n = (10 * (n & mask)) + h->digits[rx++];\n    h->digits[wx++] = new_digit;\n  }\n\n  // Put down trailing digits, left to right.\n  while (n > 0) {\n    uint8_t new_digit = ((uint8_t)(n >> shift));\n    n = 10 * (n & mask);\n    if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {\n      h->digits[wx++] = new_digit;\n    } else if (new_digit > 0) {\n      h->truncated = true;\n    }\n  }\n\n  // Finish.\n  h->num_digits = wx;\n  wuffs_base__private_implementation__high_prec_dec__trim(h);\n}\n\nstatic void  //\nwuffs_base__private_implementation__high_prec_dec__lshift(\n    wuffs_base__private_implementation__high_prec_dec* h,\n    int32_t shift) {\n  if (shift > 0) {\n    while (shift > +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {\n      wuffs_base__private_implementation__high_prec_dec__small_lshift(\n         " +
-	" h, WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL);\n      shift -= WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n    }\n    wuffs_base__private_implementation__high_prec_dec__small_lshift(\n        h, ((uint32_t)(+shift)));\n  } else if (shift < 0) {\n    while (shift < -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {\n      wuffs_base__private_implementation__high_prec_dec__small_rshift(\n          h, WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL);\n      shift += WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n    }\n    wuffs_base__private_implementation__high_prec_dec__small_rshift(\n        h, ((uint32_t)(-shift)));\n  }\n}\n\n" +
+	"c_dec__trim(h);\n}\n\nstatic void  //\nwuffs_base__private_implementation__high_prec_dec__small_rshift(\n    wuffs_base__private_implementation__high_prec_dec* h,\n    uint32_t shift) {\n  uint32_t rx = 0;  // Read  index.\n  uint32_t wx = 0;  // Write index.\n  uint64_t n = 0;\n\n  // Pick up enough leading digits to cover the first shift.\n  while ((n >> shift) == 0) {\n    if (rx < h->num_digits) {\n      // Read a digit.\n      n = (10 * n) + h->digits[rx++];\n    } else if (n == 0) {\n      // h's number used to be zero and remains zero.\n      return;\n    } else {\n      // Read sufficient implicit trailing zeroes.\n      while ((n >> shift) == 0) {\n        n = 10 * n;\n        rx++;\n      }\n      break;\n    }\n  }\n  h->decimal_point -= ((int32_t)(rx - 1));\n  if (h->decimal_point <\n      -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {\n    // After the shift, h's number is effectively zero.\n    h->num_digits = 0;\n    h->decimal_point = 0;\n    h->truncated = false;\n    return;\n  }\n\n  // Repeat: pick up a digi" +
+	"t, put down a digit, left to right.\n  uint64_t mask = (((uint64_t)(1)) << shift) - 1;\n  while (rx < h->num_digits) {\n    uint8_t new_digit = ((uint8_t)(n >> shift));\n    n = (10 * (n & mask)) + h->digits[rx++];\n    h->digits[wx++] = new_digit;\n  }\n\n  // Put down trailing digits, left to right.\n  while (n > 0) {\n    uint8_t new_digit = ((uint8_t)(n >> shift));\n    n = 10 * (n & mask);\n    if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {\n      h->digits[wx++] = new_digit;\n    } else if (new_digit > 0) {\n      h->truncated = true;\n    }\n  }\n\n  // Finish.\n  h->num_digits = wx;\n  wuffs_base__private_implementation__high_prec_dec__trim(h);\n}\n\nstatic void  //\nwuffs_base__private_implementation__high_prec_dec__lshift(\n    wuffs_base__private_implementation__high_prec_dec* h,\n    int32_t shift) {\n  if (shift > 0) {\n    while (shift > +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {\n      wuffs_base__private_implementation__high_prec_dec__small_lshift(\n          h, WUFFS_BASE__PRIVATE_I" +
+	"MPLEMENTATION__HPD__SHIFT__MAX_INCL);\n      shift -= WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n    }\n    wuffs_base__private_implementation__high_prec_dec__small_lshift(\n        h, ((uint32_t)(+shift)));\n  } else if (shift < 0) {\n    while (shift < -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {\n      wuffs_base__private_implementation__high_prec_dec__small_rshift(\n          h, WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL);\n      shift += WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n    }\n    wuffs_base__private_implementation__high_prec_dec__small_rshift(\n        h, ((uint32_t)(-shift)));\n  }\n}\n\n" +
 	"" +
 	"// --------\n\n// wuffs_base__private_implementation__high_prec_dec__round_etc rounds h's\n// number. For those functions that take an n argument, rounding produces at\n// most n digits (which is not necessarily at most n decimal places). Negative\n// n values are ignored, as well as any n greater than or equal to h's number\n// of digits. The etc__round_just_enough function implicitly chooses an n to\n// implement WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION.\n//\n// Preconditions:\n//  - h is non-NULL.\n//  - h->decimal_point is \"not extreme\".\n//\n// \"Not extreme\" means within\n// ±WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.\n\nstatic void  //\nwuffs_base__private_implementation__high_prec_dec__round_down(\n    wuffs_base__private_implementation__high_prec_dec* h,\n    int32_t n) {\n  if ((n < 0) || (h->num_digits <= (uint32_t)n)) {\n    return;\n  }\n  h->num_digits = (uint32_t)(n);\n  wuffs_base__private_implementation__high_prec_dec__trim(h);\n}\n\nstatic void  //\nwuffs_base__private_implementation__hi" +
 	"gh_prec_dec__round_up(\n    wuffs_base__private_implementation__high_prec_dec* h,\n    int32_t n) {\n  if ((n < 0) || (h->num_digits <= (uint32_t)n)) {\n    return;\n  }\n\n  for (n--; n >= 0; n--) {\n    if (h->digits[n] < 9) {\n      h->digits[n]++;\n      h->num_digits = (uint32_t)(n + 1);\n      return;\n    }\n  }\n\n  // The number is all 9s. Change to a single 1 and adjust the decimal point.\n  h->digits[0] = 1;\n  h->num_digits = 1;\n  h->decimal_point++;\n}\n\nstatic void  //\nwuffs_base__private_implementation__high_prec_dec__round_nearest(\n    wuffs_base__private_implementation__high_prec_dec* h,\n    int32_t n) {\n  if ((n < 0) || (h->num_digits <= (uint32_t)n)) {\n    return;\n  }\n  bool up = h->digits[n] >= 5;\n  if ((h->digits[n] == 5) && ((n + 1) == ((int32_t)(h->num_digits)))) {\n    up = h->truncated ||  //\n         ((n > 0) && ((h->digits[n - 1] & 1) != 0));\n  }\n\n  if (up) {\n    wuffs_base__private_implementation__high_prec_dec__round_up(h, n);\n  } else {\n    wuffs_base__private_implementation__high_prec_dec__round_do" +
@@ -397,19 +397,20 @@
 	"')) {\n          break;\n        } else if (((q - p) < 5) ||                     //\n                   ((p[0] != 'I') && (p[0] != 'i')) ||  //\n                   ((p[1] != 'N') && (p[1] != 'n')) ||  //\n                   ((p[2] != 'I') && (p[2] != 'i')) ||  //\n                   ((p[3] != 'T') && (p[3] != 't')) ||  //\n                   ((p[4] != 'Y') && (p[4] != 'y'))) {\n          goto fail;\n        }\n        p += 5;\n\n        if ((p >= q) || (*p == '_')) {\n          break;\n        }\n        goto fail;\n\n      case 'N':\n      case 'n':\n        if (((q - p) < 3) ||                     //\n            ((p[1] != 'A') && (p[1] != 'a')) ||  //\n            ((p[2] != 'N') && (p[2] != 'n'))) {\n          goto fail;\n        }\n        p += 3;\n\n        if ((p >= q) || (*p == '_')) {\n          nan = true;\n          break;\n        }\n        goto fail;\n\n      default:\n        goto fail;\n    }\n\n    // Finish.\n    for (; (p < q) && (*p == '_'); p++) {\n    }\n    if (p != q) {\n      goto fail;\n    }\n    wuffs_base__result_f64 ret;\n" +
 	"    ret.status.repr = NULL;\n    ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(\n        (nan ? 0x7FFFFFFFFFFFFFFF : 0x7FF0000000000000) |\n        (negative ? 0x8000000000000000 : 0));\n    return ret;\n  } while (0);\n\nfail:\n  do {\n    wuffs_base__result_f64 ret;\n    ret.status.repr = wuffs_base__error__bad_argument;\n    ret.value = 0;\n    return ret;\n  } while (0);\n}\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //\nwuffs_base__private_implementation__high_prec_dec__to_f64(\n    wuffs_base__private_implementation__high_prec_dec* h,\n    uint32_t options) {\n  do {\n    // powers converts decimal powers of 10 to binary powers of 2. For example,\n    // (10000 >> 13) is 1. It stops before the elements exceed 60, also known\n    // as WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.\n    static const uint32_t num_powers = 19;\n    static const uint8_t powers[19] = {\n        0,  3,  6,  9,  13, 16, 19, 23, 26, 29,  //\n        33, 36, 39, 43, 46, 49, 53, 56, 59,      //\n    };\n\n    // Handl" +
 	"e zero and obvious extremes. The largest and smallest positive\n    // finite f64 values are approximately 1.8e+308 and 4.9e-324.\n    if ((h->num_digits == 0) || (h->decimal_point < -326)) {\n      goto zero;\n    } else if (h->decimal_point > 310) {\n      goto infinity;\n    }\n\n    // Try the fast Eisel-Lemire algorithm again. Calculating the (man, exp10)\n    // pair from the high_prec_dec h is more correct but slower than the\n    // approach taken in wuffs_base__parse_number_f64. The latter is optimized\n    // for the common cases (e.g. assuming no underscores or a leading '+'\n    // sign) rather than the full set of cases allowed by the Wuffs API.\n    if (h->num_digits <= 19) {\n      uint64_t man = 0;\n      uint32_t i;\n      for (i = 0; i < h->num_digits; i++) {\n        man = (10 * man) + h->digits[i];\n      }\n      int32_t exp10 = h->decimal_point - ((int32_t)(h->num_digits));\n      if ((man != 0) && (-307 <= exp10) && (exp10 <= 288)) {\n        int64_t r =\n            wuffs_base__private_implementation__parse" +
-	"_number_f64_eisel_lemire(\n                man, exp10);\n        if (r >= 0) {\n          wuffs_base__result_f64 ret;\n          ret.status.repr = NULL;\n          ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(\n              ((uint64_t)r) | (((uint64_t)(h->negative)) << 63));\n          return ret;\n        }\n      }\n    }\n\n    // Scale by powers of 2 until we're in the range [½ .. 1], which gives us\n    // our exponent (in base-2). First we shift right, possibly a little too\n    // far, ending with a value certainly below 1 and possibly below ½...\n    const int32_t f64_bias = -1023;\n    int32_t exp2 = 0;\n    while (h->decimal_point > 0) {\n      uint32_t n = (uint32_t)(+h->decimal_point);\n      uint32_t shift =\n          (n < num_powers)\n              ? powers[n]\n              : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n\n      wuffs_base__private_implementation__high_prec_dec__small_rshift(h, shift);\n      if (h->decimal_point <\n          -WUFFS_BASE__PRIVATE_IMPLEMENTATION__" +
-	"HPD__DECIMAL_POINT__RANGE) {\n        goto zero;\n      }\n      exp2 += (int32_t)shift;\n    }\n    // ...then we shift left, putting us in [½ .. 1].\n    while (h->decimal_point <= 0) {\n      uint32_t shift;\n      if (h->decimal_point == 0) {\n        if (h->digits[0] >= 5) {\n          break;\n        }\n        shift = (h->digits[0] < 2) ? 2 : 1;\n      } else {\n        uint32_t n = (uint32_t)(-h->decimal_point);\n        shift = (n < num_powers)\n                    ? powers[n]\n                    : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n      }\n\n      wuffs_base__private_implementation__high_prec_dec__small_lshift(h, shift);\n      if (h->decimal_point >\n          +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {\n        goto infinity;\n      }\n      exp2 -= (int32_t)shift;\n    }\n\n    // We're in the range [½ .. 1] but f64 uses [1 .. 2].\n    exp2--;\n\n    // The minimum normal exponent is (f64_bias + 1).\n    while ((f64_bias + 1) > exp2) {\n      uint32_t n = (uint32_t)((f64_bias + 1" +
-	") - exp2);\n      if (n > WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {\n        n = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n      }\n      wuffs_base__private_implementation__high_prec_dec__small_rshift(h, n);\n      exp2 += (int32_t)n;\n    }\n\n    // Check for overflow.\n    if ((exp2 - f64_bias) >= 0x07FF) {  // (1 << 11) - 1.\n      goto infinity;\n    }\n\n    // Extract 53 bits for the mantissa (in base-2).\n    wuffs_base__private_implementation__high_prec_dec__small_lshift(h, 53);\n    uint64_t man2 =\n        wuffs_base__private_implementation__high_prec_dec__rounded_integer(h);\n\n    // Rounding might have added one bit. If so, shift and re-check overflow.\n    if ((man2 >> 53) != 0) {\n      man2 >>= 1;\n      exp2++;\n      if ((exp2 - f64_bias) >= 0x07FF) {  // (1 << 11) - 1.\n        goto infinity;\n      }\n    }\n\n    // Handle subnormal numbers.\n    if ((man2 >> 52) == 0) {\n      exp2 = f64_bias;\n    }\n\n    // Pack the bits and return.\n    uint64_t exp2_bits =\n        (uint64_t)((ex" +
-	"p2 - f64_bias) & 0x07FF);              // (1 << 11) - 1.\n    uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) |            // (1 << 52) - 1.\n                    (exp2_bits << 52) |                      //\n                    (h->negative ? 0x8000000000000000 : 0);  // (1 << 63).\n\n    wuffs_base__result_f64 ret;\n    ret.status.repr = NULL;\n    ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);\n    return ret;\n  } while (0);\n\nzero:\n  do {\n    uint64_t bits = h->negative ? 0x8000000000000000 : 0;\n\n    wuffs_base__result_f64 ret;\n    ret.status.repr = NULL;\n    ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);\n    return ret;\n  } while (0);\n\ninfinity:\n  do {\n    if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) {\n      wuffs_base__result_f64 ret;\n      ret.status.repr = wuffs_base__error__bad_argument;\n      ret.value = 0;\n      return ret;\n    }\n\n    uint64_t bits = h->negative ? 0xFFF0000000000000 : 0x7FF0000000000000;\n\n    wuffs_base__result_f64 ret;\n" +
-	"    ret.status.repr = NULL;\n    ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);\n    return ret;\n  } while (0);\n}\n\nstatic inline bool  //\nwuffs_base__private_implementation__is_decimal_digit(uint8_t c) {\n  return ('0' <= c) && (c <= '9');\n}\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //\nwuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options) {\n  // In practice, almost all \"dd.ddddE±xxx\" numbers can be represented\n  // losslessly by a uint64_t mantissa \"dddddd\" and an int32_t base-10\n  // exponent, adjusting \"xxx\" for the position (if present) of the decimal\n  // separator '.' or ','.\n  //\n  // This (u64 man, i32 exp10) data structure is superficially similar to the\n  // \"Do It Yourself Floating Point\" type from Loitsch (†), but the exponent\n  // here is base-10, not base-2.\n  //\n  // If s's number fits in a (man, exp10), parse that pair with the\n  // Eisel-Lemire algorithm. If not, or if Eisel-Lemire fails, parsing s with\n  // the fallback algorithm is slower" +
-	" but comprehensive.\n  //\n  // † \"Printing Floating-Point Numbers Quickly and Accurately with Integers\"\n  // (https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf).\n  // Florian Loitsch is also the primary contributor to\n  // https://github.com/google/double-conversion\n  do {\n    // Calculating that (man, exp10) pair needs to stay within s's bounds.\n    // Provided that s isn't extremely long, work on a NUL-terminated copy of\n    // s's contents. The NUL byte isn't a valid part of \"±dd.ddddE±xxx\".\n    //\n    // As the pointer p walks the contents, it's faster to repeatedly check \"is\n    // *p a valid digit\" than \"is p within bounds and *p a valid digit\".\n    if (s.len >= 256) {\n      goto fallback;\n    }\n    uint8_t z[256];\n    memcpy(&z[0], s.ptr, s.len);\n    z[s.len] = 0;\n    const uint8_t* p = &z[0];\n\n    // Look for a leading minus sign. Technically, we could also look for an\n    // optional plus sign, but the \"script/process-json-numbers.c with -p\"\n    // benchmark is noticably slower" +
-	" if we do. It's optional and, in practice,\n    // usually absent. Let the fallback catch it.\n    bool negative = (*p == '-');\n    if (negative) {\n      p++;\n    }\n\n    // After walking \"dd.dddd\", comparing p later with p now will produce the\n    // number of \"d\"s and \".\"s.\n    const uint8_t* const start_of_digits_ptr = p;\n\n    // Walk the \"d\"s before a '.', 'E', NUL byte, etc. If it starts with '0',\n    // it must be a single '0'. If it starts with a non-zero decimal digit, it\n    // can be a sequence of decimal digits.\n    //\n    // Update the man variable during the walk. It's OK if man overflows now.\n    // We'll detect that later.\n    uint64_t man;\n    if (*p == '0') {\n      man = 0;\n      p++;\n      if (wuffs_base__private_implementation__is_decimal_digit(*p)) {\n        goto fallback;\n      }\n    } else if (wuffs_base__private_implementation__is_decimal_digit(*p)) {\n      man = ((uint8_t)(*p - '0'));\n      p++;\n      for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) {\n        man = (1" +
-	"0 * man) + ((uint8_t)(*p - '0'));\n      }\n    } else {\n      goto fallback;\n    }\n\n    // Walk the \"d\"s after the optional decimal separator ('.' or ','),\n    // updating the man and exp10 variables.\n    int32_t exp10 = 0;\n    if (*p ==\n        ((options & WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)\n             ? ','\n             : '.')) {\n      p++;\n      const uint8_t* first_after_separator_ptr = p;\n      if (!wuffs_base__private_implementation__is_decimal_digit(*p)) {\n        goto fallback;\n      }\n      man = (10 * man) + ((uint8_t)(*p - '0'));\n      p++;\n      for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) {\n        man = (10 * man) + ((uint8_t)(*p - '0'));\n      }\n      exp10 = ((int32_t)(first_after_separator_ptr - p));\n    }\n\n    // Count the number of digits:\n    //  - for an input of \"314159\",  digit_count is 6.\n    //  - for an input of \"3.14159\", digit_count is 7.\n    //\n    // This is off-by-one if there is a decimal separator. That's OK for now.\n    // We'" +
-	"ll correct for that later. The \"script/process-json-numbers.c with\n    // -p\" benchmark is noticably slower if we try to correct for that now.\n    uint32_t digit_count = (uint32_t)(p - start_of_digits_ptr);\n\n    // Update exp10 for the optional exponent, starting with 'E' or 'e'.\n    if ((*p | 0x20) == 'e') {\n      p++;\n      int32_t exp_sign = +1;\n      if (*p == '-') {\n        p++;\n        exp_sign = -1;\n      } else if (*p == '+') {\n        p++;\n      }\n      if (!wuffs_base__private_implementation__is_decimal_digit(*p)) {\n        goto fallback;\n      }\n      int32_t exp_num = ((uint8_t)(*p - '0'));\n      p++;\n      // The rest of the exp_num walking has a peculiar control flow but, once\n      // again, the \"script/process-json-numbers.c with -p\" benchmark is\n      // sensitive to alternative formulations.\n      if (wuffs_base__private_implementation__is_decimal_digit(*p)) {\n        exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));\n        p++;\n      }\n      if (wuffs_base__private_implementation__is_decim" +
-	"al_digit(*p)) {\n        exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));\n        p++;\n      }\n      while (wuffs_base__private_implementation__is_decimal_digit(*p)) {\n        if (exp_num > 0x1000000) {\n          goto fallback;\n        }\n        exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));\n        p++;\n      }\n      exp10 += exp_sign * exp_num;\n    }\n\n    // The Wuffs API is that the original slice has no trailing data. It also\n    // allows underscores, which we don't catch here but the fallback should.\n    if (p != &z[s.len]) {\n      goto fallback;\n    }\n\n    // Check that the uint64_t typed man variable has not overflowed, based on\n    // digit_count.\n    //\n    // For reference:\n    //   - (1 << 63) is  9223372036854775808, which has 19 decimal digits.\n    //   - (1 << 64) is 18446744073709551616, which has 20 decimal digits.\n    //   - 19 nines,  9999999999999999999, is  0x8AC7230489E7FFFF, which has 64\n    //     bits and 16 hexadecimal digits.\n    //   - 20 nines, 99999999999999999999, is 0x56BC75" +
-	"E2D630FFFFF, which has 67\n    //     bits and 17 hexadecimal digits.\n    if (digit_count > 19) {\n      // Even if we have more than 19 pseudo-digits, it's not yet definitely an\n      // overflow. Recall that digit_count might be off-by-one (too large) if\n      // there's a decimal separator. It will also over-report the number of\n      // meaningful digits if the input looks something like \"0.000dddExxx\".\n      //\n      // We adjust by the number of leading '0's and '.'s and re-compare to 19.\n      // Once again, technically, we could skip ','s too, but that perturbs the\n      // \"script/process-json-numbers.c with -p\" benchmark.\n      const uint8_t* q = start_of_digits_ptr;\n      for (; (*q == '0') || (*q == '.'); q++) {\n      }\n      digit_count -= (uint32_t)(q - start_of_digits_ptr);\n      if (digit_count > 19) {\n        goto fallback;\n      }\n    }\n\n    // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire\n    // preconditions include that exp10 is in the range [-307 ..= 288].\n    if ((" +
-	"exp10 < -307) || (288 < exp10)) {\n      goto fallback;\n    }\n\n    // If both man and (10 ** exp10) are exactly representable by a double, we\n    // don't need to run the Eisel-Lemire algorithm.\n    if ((-22 <= exp10) && (exp10 <= 22) && ((man >> 53) == 0)) {\n      double d = (double)man;\n      if (exp10 >= 0) {\n        d *= wuffs_base__private_implementation__f64_powers_of_10[+exp10];\n      } else {\n        d /= wuffs_base__private_implementation__f64_powers_of_10[-exp10];\n      }\n      wuffs_base__result_f64 ret;\n      ret.status.repr = NULL;\n      ret.value = negative ? -d : +d;\n      return ret;\n    }\n\n    // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire\n    // preconditions include that man is non-zero. Parsing \"0\" should be caught\n    // by the \"If both man and (10 ** exp10)\" above, but \"0e99\" might not.\n    if (man == 0) {\n      goto fallback;\n    }\n\n    // Our man and exp10 are in range. Run the Eisel-Lemire algorithm.\n    int64_t r =\n        wuffs_base__private_implementation__" +
-	"parse_number_f64_eisel_lemire(\n            man, exp10);\n    if (r < 0) {\n      goto fallback;\n    }\n    wuffs_base__result_f64 ret;\n    ret.status.repr = NULL;\n    ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(\n        ((uint64_t)r) | (((uint64_t)negative) << 63));\n    return ret;\n  } while (0);\n\nfallback:\n  do {\n    wuffs_base__private_implementation__high_prec_dec h;\n    wuffs_base__status status =\n        wuffs_base__private_implementation__high_prec_dec__parse(&h, s,\n                                                                 options);\n    if (status.repr) {\n      return wuffs_base__private_implementation__parse_number_f64_special(\n          s, options);\n    }\n    return wuffs_base__private_implementation__high_prec_dec__to_f64(&h,\n                                                                     options);\n  } while (0);\n}\n\n" +
+	"_number_f64_eisel_lemire(\n                man, exp10);\n        if (r >= 0) {\n          wuffs_base__result_f64 ret;\n          ret.status.repr = NULL;\n          ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(\n              ((uint64_t)r) | (((uint64_t)(h->negative)) << 63));\n          return ret;\n        }\n      }\n    }\n\n    // When Eisel-Lemire fails, fall back to Simple Decimal Conversion. See\n    // https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html\n    //\n    // Scale by powers of 2 until we're in the range [½ .. 1], which gives us\n    // our exponent (in base-2). First we shift right, possibly a little too\n    // far, ending with a value certainly below 1 and possibly below ½...\n    const int32_t f64_bias = -1023;\n    int32_t exp2 = 0;\n    while (h->decimal_point > 0) {\n      uint32_t n = (uint32_t)(+h->decimal_point);\n      uint32_t shift =\n          (n < num_powers)\n              ? powers[n]\n              : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n\n " +
+	"     wuffs_base__private_implementation__high_prec_dec__small_rshift(h, shift);\n      if (h->decimal_point <\n          -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {\n        goto zero;\n      }\n      exp2 += (int32_t)shift;\n    }\n    // ...then we shift left, putting us in [½ .. 1].\n    while (h->decimal_point <= 0) {\n      uint32_t shift;\n      if (h->decimal_point == 0) {\n        if (h->digits[0] >= 5) {\n          break;\n        }\n        shift = (h->digits[0] < 2) ? 2 : 1;\n      } else {\n        uint32_t n = (uint32_t)(-h->decimal_point);\n        shift = (n < num_powers)\n                    ? powers[n]\n                    : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n      }\n\n      wuffs_base__private_implementation__high_prec_dec__small_lshift(h, shift);\n      if (h->decimal_point >\n          +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {\n        goto infinity;\n      }\n      exp2 -= (int32_t)shift;\n    }\n\n    // We're in the range [½ .. 1] but f64 uses " +
+	"[1 .. 2].\n    exp2--;\n\n    // The minimum normal exponent is (f64_bias + 1).\n    while ((f64_bias + 1) > exp2) {\n      uint32_t n = (uint32_t)((f64_bias + 1) - exp2);\n      if (n > WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {\n        n = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;\n      }\n      wuffs_base__private_implementation__high_prec_dec__small_rshift(h, n);\n      exp2 += (int32_t)n;\n    }\n\n    // Check for overflow.\n    if ((exp2 - f64_bias) >= 0x07FF) {  // (1 << 11) - 1.\n      goto infinity;\n    }\n\n    // Extract 53 bits for the mantissa (in base-2).\n    wuffs_base__private_implementation__high_prec_dec__small_lshift(h, 53);\n    uint64_t man2 =\n        wuffs_base__private_implementation__high_prec_dec__rounded_integer(h);\n\n    // Rounding might have added one bit. If so, shift and re-check overflow.\n    if ((man2 >> 53) != 0) {\n      man2 >>= 1;\n      exp2++;\n      if ((exp2 - f64_bias) >= 0x07FF) {  // (1 << 11) - 1.\n        goto infinity;\n      }\n    }\n\n    // Handle su" +
+	"bnormal numbers.\n    if ((man2 >> 52) == 0) {\n      exp2 = f64_bias;\n    }\n\n    // Pack the bits and return.\n    uint64_t exp2_bits =\n        (uint64_t)((exp2 - f64_bias) & 0x07FF);              // (1 << 11) - 1.\n    uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) |            // (1 << 52) - 1.\n                    (exp2_bits << 52) |                      //\n                    (h->negative ? 0x8000000000000000 : 0);  // (1 << 63).\n\n    wuffs_base__result_f64 ret;\n    ret.status.repr = NULL;\n    ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);\n    return ret;\n  } while (0);\n\nzero:\n  do {\n    uint64_t bits = h->negative ? 0x8000000000000000 : 0;\n\n    wuffs_base__result_f64 ret;\n    ret.status.repr = NULL;\n    ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);\n    return ret;\n  } while (0);\n\ninfinity:\n  do {\n    if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) {\n      wuffs_base__result_f64 ret;\n      ret.status.repr = wuffs_base__error__bad_argument" +
+	";\n      ret.value = 0;\n      return ret;\n    }\n\n    uint64_t bits = h->negative ? 0xFFF0000000000000 : 0x7FF0000000000000;\n\n    wuffs_base__result_f64 ret;\n    ret.status.repr = NULL;\n    ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);\n    return ret;\n  } while (0);\n}\n\nstatic inline bool  //\nwuffs_base__private_implementation__is_decimal_digit(uint8_t c) {\n  return ('0' <= c) && (c <= '9');\n}\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64  //\nwuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options) {\n  // In practice, almost all \"dd.ddddE±xxx\" numbers can be represented\n  // losslessly by a uint64_t mantissa \"dddddd\" and an int32_t base-10\n  // exponent, adjusting \"xxx\" for the position (if present) of the decimal\n  // separator '.' or ','.\n  //\n  // This (u64 man, i32 exp10) data structure is superficially similar to the\n  // \"Do It Yourself Floating Point\" type from Loitsch (†), but the exponent\n  // here is base-10, not base-2.\n  //\n  // If s's number fits in " +
+	"a (man, exp10), parse that pair with the\n  // Eisel-Lemire algorithm. If not, or if Eisel-Lemire fails, parsing s with\n  // the fallback algorithm is slower but comprehensive.\n  //\n  // † \"Printing Floating-Point Numbers Quickly and Accurately with Integers\"\n  // (https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf).\n  // Florian Loitsch is also the primary contributor to\n  // https://github.com/google/double-conversion\n  do {\n    // Calculating that (man, exp10) pair needs to stay within s's bounds.\n    // Provided that s isn't extremely long, work on a NUL-terminated copy of\n    // s's contents. The NUL byte isn't a valid part of \"±dd.ddddE±xxx\".\n    //\n    // As the pointer p walks the contents, it's faster to repeatedly check \"is\n    // *p a valid digit\" than \"is p within bounds and *p a valid digit\".\n    if (s.len >= 256) {\n      goto fallback;\n    }\n    uint8_t z[256];\n    memcpy(&z[0], s.ptr, s.len);\n    z[s.len] = 0;\n    const uint8_t* p = &z[0];\n\n    // Look for a leading minus " +
+	"sign. Technically, we could also look for an\n    // optional plus sign, but the \"script/process-json-numbers.c with -p\"\n    // benchmark is noticably slower if we do. It's optional and, in practice,\n    // usually absent. Let the fallback catch it.\n    bool negative = (*p == '-');\n    if (negative) {\n      p++;\n    }\n\n    // After walking \"dd.dddd\", comparing p later with p now will produce the\n    // number of \"d\"s and \".\"s.\n    const uint8_t* const start_of_digits_ptr = p;\n\n    // Walk the \"d\"s before a '.', 'E', NUL byte, etc. If it starts with '0',\n    // it must be a single '0'. If it starts with a non-zero decimal digit, it\n    // can be a sequence of decimal digits.\n    //\n    // Update the man variable during the walk. It's OK if man overflows now.\n    // We'll detect that later.\n    uint64_t man;\n    if (*p == '0') {\n      man = 0;\n      p++;\n      if (wuffs_base__private_implementation__is_decimal_digit(*p)) {\n        goto fallback;\n      }\n    } else if (wuffs_base__private_implementation__is_decim" +
+	"al_digit(*p)) {\n      man = ((uint8_t)(*p - '0'));\n      p++;\n      for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) {\n        man = (10 * man) + ((uint8_t)(*p - '0'));\n      }\n    } else {\n      goto fallback;\n    }\n\n    // Walk the \"d\"s after the optional decimal separator ('.' or ','),\n    // updating the man and exp10 variables.\n    int32_t exp10 = 0;\n    if (*p ==\n        ((options & WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)\n             ? ','\n             : '.')) {\n      p++;\n      const uint8_t* first_after_separator_ptr = p;\n      if (!wuffs_base__private_implementation__is_decimal_digit(*p)) {\n        goto fallback;\n      }\n      man = (10 * man) + ((uint8_t)(*p - '0'));\n      p++;\n      for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) {\n        man = (10 * man) + ((uint8_t)(*p - '0'));\n      }\n      exp10 = ((int32_t)(first_after_separator_ptr - p));\n    }\n\n    // Count the number of digits:\n    //  - for an input of \"314159\",  digit_count " +
+	"is 6.\n    //  - for an input of \"3.14159\", digit_count is 7.\n    //\n    // This is off-by-one if there is a decimal separator. That's OK for now.\n    // We'll correct for that later. The \"script/process-json-numbers.c with\n    // -p\" benchmark is noticably slower if we try to correct for that now.\n    uint32_t digit_count = (uint32_t)(p - start_of_digits_ptr);\n\n    // Update exp10 for the optional exponent, starting with 'E' or 'e'.\n    if ((*p | 0x20) == 'e') {\n      p++;\n      int32_t exp_sign = +1;\n      if (*p == '-') {\n        p++;\n        exp_sign = -1;\n      } else if (*p == '+') {\n        p++;\n      }\n      if (!wuffs_base__private_implementation__is_decimal_digit(*p)) {\n        goto fallback;\n      }\n      int32_t exp_num = ((uint8_t)(*p - '0'));\n      p++;\n      // The rest of the exp_num walking has a peculiar control flow but, once\n      // again, the \"script/process-json-numbers.c with -p\" benchmark is\n      // sensitive to alternative formulations.\n      if (wuffs_base__private_implementation__i" +
+	"s_decimal_digit(*p)) {\n        exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));\n        p++;\n      }\n      if (wuffs_base__private_implementation__is_decimal_digit(*p)) {\n        exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));\n        p++;\n      }\n      while (wuffs_base__private_implementation__is_decimal_digit(*p)) {\n        if (exp_num > 0x1000000) {\n          goto fallback;\n        }\n        exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));\n        p++;\n      }\n      exp10 += exp_sign * exp_num;\n    }\n\n    // The Wuffs API is that the original slice has no trailing data. It also\n    // allows underscores, which we don't catch here but the fallback should.\n    if (p != &z[s.len]) {\n      goto fallback;\n    }\n\n    // Check that the uint64_t typed man variable has not overflowed, based on\n    // digit_count.\n    //\n    // For reference:\n    //   - (1 << 63) is  9223372036854775808, which has 19 decimal digits.\n    //   - (1 << 64) is 18446744073709551616, which has 20 decimal digits.\n    //   - 19 nines, " +
+	" 9999999999999999999, is  0x8AC7230489E7FFFF, which has 64\n    //     bits and 16 hexadecimal digits.\n    //   - 20 nines, 99999999999999999999, is 0x56BC75E2D630FFFFF, which has 67\n    //     bits and 17 hexadecimal digits.\n    if (digit_count > 19) {\n      // Even if we have more than 19 pseudo-digits, it's not yet definitely an\n      // overflow. Recall that digit_count might be off-by-one (too large) if\n      // there's a decimal separator. It will also over-report the number of\n      // meaningful digits if the input looks something like \"0.000dddExxx\".\n      //\n      // We adjust by the number of leading '0's and '.'s and re-compare to 19.\n      // Once again, technically, we could skip ','s too, but that perturbs the\n      // \"script/process-json-numbers.c with -p\" benchmark.\n      const uint8_t* q = start_of_digits_ptr;\n      for (; (*q == '0') || (*q == '.'); q++) {\n      }\n      digit_count -= (uint32_t)(q - start_of_digits_ptr);\n      if (digit_count > 19) {\n        goto fallback;\n      }\n    }\n\n  " +
+	"  // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire\n    // preconditions include that exp10 is in the range [-307 ..= 288].\n    if ((exp10 < -307) || (288 < exp10)) {\n      goto fallback;\n    }\n\n    // If both man and (10 ** exp10) are exactly representable by a double, we\n    // don't need to run the Eisel-Lemire algorithm.\n    if ((-22 <= exp10) && (exp10 <= 22) && ((man >> 53) == 0)) {\n      double d = (double)man;\n      if (exp10 >= 0) {\n        d *= wuffs_base__private_implementation__f64_powers_of_10[+exp10];\n      } else {\n        d /= wuffs_base__private_implementation__f64_powers_of_10[-exp10];\n      }\n      wuffs_base__result_f64 ret;\n      ret.status.repr = NULL;\n      ret.value = negative ? -d : +d;\n      return ret;\n    }\n\n    // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire\n    // preconditions include that man is non-zero. Parsing \"0\" should be caught\n    // by the \"If both man and (10 ** exp10)\" above, but \"0e99\" might not.\n    if (man == 0) {\n   " +
+	"   goto fallback;\n    }\n\n    // Our man and exp10 are in range. Run the Eisel-Lemire algorithm.\n    int64_t r =\n        wuffs_base__private_implementation__parse_number_f64_eisel_lemire(\n            man, exp10);\n    if (r < 0) {\n      goto fallback;\n    }\n    wuffs_base__result_f64 ret;\n    ret.status.repr = NULL;\n    ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(\n        ((uint64_t)r) | (((uint64_t)negative) << 63));\n    return ret;\n  } while (0);\n\nfallback:\n  do {\n    wuffs_base__private_implementation__high_prec_dec h;\n    wuffs_base__status status =\n        wuffs_base__private_implementation__high_prec_dec__parse(&h, s,\n                                                                 options);\n    if (status.repr) {\n      return wuffs_base__private_implementation__parse_number_f64_special(\n          s, options);\n    }\n    return wuffs_base__private_implementation__high_prec_dec__to_f64(&h,\n                                                                     options);\n  } while (0);\n" +
+	"}\n\n" +
 	"" +
 	"// --------\n\nstatic inline size_t  //\nwuffs_base__private_implementation__render_inf(wuffs_base__slice_u8 dst,\n                                               bool neg,\n                                               uint32_t options) {\n  if (neg) {\n    if (dst.len < 4) {\n      return 0;\n    }\n    wuffs_base__store_u32le__no_bounds_check(dst.ptr, 0x666E492D);  // '-Inf'le.\n    return 4;\n  }\n\n  if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {\n    if (dst.len < 4) {\n      return 0;\n    }\n    wuffs_base__store_u32le__no_bounds_check(dst.ptr, 0x666E492B);  // '+Inf'le.\n    return 4;\n  }\n\n  if (dst.len < 3) {\n    return 0;\n  }\n  wuffs_base__store_u24le__no_bounds_check(dst.ptr, 0x666E49);  // 'Inf'le.\n  return 3;\n}\n\nstatic inline size_t  //\nwuffs_base__private_implementation__render_nan(wuffs_base__slice_u8 dst) {\n  if (dst.len < 3) {\n    return 0;\n  }\n  wuffs_base__store_u24le__no_bounds_check(dst.ptr, 0x4E614E);  // 'NaN'le.\n  return 3;\n}\n\nstatic size_t  //\nwuffs_base__private_implementation__high" +
 	"_prec_dec__render_exponent_absent(\n    wuffs_base__slice_u8 dst,\n    wuffs_base__private_implementation__high_prec_dec* h,\n    uint32_t precision,\n    uint32_t options) {\n  size_t n = (h->negative ||\n              (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN))\n                 ? 1\n                 : 0;\n  if (h->decimal_point <= 0) {\n    n += 1;\n  } else {\n    n += (size_t)(h->decimal_point);\n  }\n  if (precision > 0) {\n    n += precision + 1;  // +1 for the '.'.\n  }\n\n  // Don't modify dst if the formatted number won't fit.\n  if (n > dst.len) {\n    return 0;\n  }\n\n  // Align-left or align-right.\n  uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)\n                     ? &dst.ptr[dst.len - n]\n                     : &dst.ptr[0];\n\n  // Leading \"±\".\n  if (h->negative) {\n    *ptr++ = '-';\n  } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {\n    *ptr++ = '+';\n  }\n\n  // Integral digits.\n  if (h->decimal_point <= 0) {\n    *ptr++ = '0';\n  } else {\n    uint32_t m =\n" +
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 946dad3..e0e7078 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -11234,7 +11234,6 @@
     // After the shift, h's number is effectively zero.
     h->num_digits = 0;
     h->decimal_point = 0;
-    h->negative = false;
     h->truncated = false;
     return;
   }
@@ -11861,6 +11860,9 @@
       }
     }
 
+    // When Eisel-Lemire fails, fall back to Simple Decimal Conversion. See
+    // https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html
+    //
     // Scale by powers of 2 until we're in the range [½ .. 1], which gives us
     // our exponent (in base-2). First we shift right, possibly a little too
     // far, ending with a value certainly below 1 and possibly below ½...