Refactor f64conv's wuffs_base__parse_number_f64
Binary size, before:
27704 gen/lib/c/clang-5.0-dynamic/wuffs-base-f64conv.lo
27896 gen/lib/c/clang-5.0-static/wuffs-base-f64conv.o
29120 gen/lib/c/gcc-dynamic/wuffs-base-f64conv.lo
29120 gen/lib/c/gcc-static/wuffs-base-f64conv.o
After:
27848 gen/lib/c/clang-5.0-dynamic/wuffs-base-f64conv.lo
28040 gen/lib/c/clang-5.0-static/wuffs-base-f64conv.o
30392 gen/lib/c/gcc-dynamic/wuffs-base-f64conv.lo
30392 gen/lib/c/gcc-static/wuffs-base-f64conv.o
$ g++ -O3 script/process-json-numbers.c
$ time ./a.out -parse-number-f64 < citylots.json
Before/After:
real 0m1.306s
real 0m1.231s
citylots.json is from github.com/zemirco/sf-city-lots-json
name old time/op new time/op delta
wuffs_strconv_parse_number_f64_1_lsh53_add0/clang5 73.2ns ± 2% 77.0ns ± 0% +5.19% (p=0.016 n=5+4)
wuffs_strconv_parse_number_f64_1_lsh53_add1/clang5 688ns ± 0% 690ns ± 0% ~ (p=0.079 n=5+5)
wuffs_strconv_parse_number_f64_pi_long/clang5 113ns ± 1% 92ns ± 0% -18.44% (p=0.000 n=5+4)
wuffs_strconv_parse_number_f64_pi_short/clang5 35.4ns ± 7% 35.0ns ± 3% ~ (p=1.000 n=5+5)
wuffs_strconv_parse_number_f64_1_lsh53_add0/gcc7 67.0ns ± 0% 67.0ns ± 0% ~ (all equal)
wuffs_strconv_parse_number_f64_1_lsh53_add1/gcc7 721ns ± 0% 712ns ± 0% -1.30% (p=0.008 n=5+5)
wuffs_strconv_parse_number_f64_pi_long/gcc7 90.4ns ± 1% 88.4ns ± 1% -2.21% (p=0.008 n=5+5)
wuffs_strconv_parse_number_f64_pi_short/gcc7 32.2ns ± 6% 32.6ns ± 2% ~ (p=0.730 n=5+5)
diff --git a/internal/cgen/base/f64conv-submodule.c b/internal/cgen/base/f64conv-submodule.c
index 05fff67..c1630b0 100644
--- a/internal/cgen/base/f64conv-submodule.c
+++ b/internal/cgen/base/f64conv-submodule.c
@@ -2007,10 +2007,8 @@
}
WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //
-wuffs_base__parse_number_f64(wuffs_base__slice_u8 s) {
- wuffs_base__private_implementation__medium_prec_bin m;
- wuffs_base__private_implementation__high_prec_dec h;
-
+wuffs_base__private_implementation__parse_number_f64__fallback(
+ wuffs_base__private_implementation__high_prec_dec* h) {
do {
// powers converts decimal powers of 10 to binary powers of 2. For example,
// (10000 >> 13) is 1. It stops before the elements exceed 60, also known
@@ -2021,23 +2019,18 @@
33, 36, 39, 43, 46, 49, 53, 56, 59, //
};
- wuffs_base__status status =
- wuffs_base__private_implementation__high_prec_dec__parse(&h, s);
- if (status.repr) {
- return wuffs_base__parse_number_f64_special(s, status.repr);
- }
-
// Handle zero and obvious extremes. The largest and smallest positive
// finite f64 values are approximately 1.8e+308 and 4.9e-324.
- if ((h.num_digits == 0) || (h.decimal_point < -326)) {
+ if ((h->num_digits == 0) || (h->decimal_point < -326)) {
goto zero;
- } else if (h.decimal_point > 310) {
+ } else if (h->decimal_point > 310) {
goto infinity;
}
+ wuffs_base__private_implementation__medium_prec_bin m;
wuffs_base__result_f64 mpb_result =
wuffs_base__private_implementation__medium_prec_bin__parse_number_f64(
- &m, &h, false);
+ &m, h, false);
if (mpb_result.status.repr == NULL) {
return mpb_result;
}
@@ -2047,39 +2040,37 @@
// far, ending with a value certainly below 1 and possibly below ½...
const int32_t f64_bias = -1023;
int32_t exp2 = 0;
- while (h.decimal_point > 0) {
- uint32_t n = (uint32_t)(+h.decimal_point);
+ while (h->decimal_point > 0) {
+ uint32_t n = (uint32_t)(+h->decimal_point);
uint32_t shift =
(n < num_powers)
? powers[n]
: WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
- wuffs_base__private_implementation__high_prec_dec__small_rshift(&h,
- shift);
- if (h.decimal_point <
+ wuffs_base__private_implementation__high_prec_dec__small_rshift(h, shift);
+ if (h->decimal_point <
-WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
goto zero;
}
exp2 += (int32_t)shift;
}
// ...then we shift left, putting us in [½ .. 1].
- while (h.decimal_point <= 0) {
+ while (h->decimal_point <= 0) {
uint32_t shift;
- if (h.decimal_point == 0) {
- if (h.digits[0] >= 5) {
+ if (h->decimal_point == 0) {
+ if (h->digits[0] >= 5) {
break;
}
- shift = (h.digits[0] <= 2) ? 2 : 1;
+ shift = (h->digits[0] <= 2) ? 2 : 1;
} else {
- uint32_t n = (uint32_t)(-h.decimal_point);
+ uint32_t n = (uint32_t)(-h->decimal_point);
shift = (n < num_powers)
? powers[n]
: WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
}
- wuffs_base__private_implementation__high_prec_dec__small_lshift(&h,
- shift);
- if (h.decimal_point >
+ wuffs_base__private_implementation__high_prec_dec__small_lshift(h, shift);
+ if (h->decimal_point >
+WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
goto infinity;
}
@@ -2095,7 +2086,7 @@
if (n > WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
n = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
}
- wuffs_base__private_implementation__high_prec_dec__small_rshift(&h, n);
+ wuffs_base__private_implementation__high_prec_dec__small_rshift(h, n);
exp2 += (int32_t)n;
}
@@ -2105,9 +2096,9 @@
}
// Extract 53 bits for the mantissa (in base-2).
- wuffs_base__private_implementation__high_prec_dec__small_lshift(&h, 53);
+ wuffs_base__private_implementation__high_prec_dec__small_lshift(h, 53);
uint64_t man2 =
- wuffs_base__private_implementation__high_prec_dec__rounded_integer(&h);
+ wuffs_base__private_implementation__high_prec_dec__rounded_integer(h);
// Rounding might have added one bit. If so, shift and re-check overflow.
if ((man2 >> 53) != 0) {
@@ -2125,10 +2116,10 @@
// Pack the bits and return.
uint64_t exp2_bits =
- (uint64_t)((exp2 - f64_bias) & 0x07FF); // (1 << 11) - 1.
- uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) | // (1 << 52) - 1.
- (exp2_bits << 52) | //
- (h.negative ? 0x8000000000000000 : 0); // (1 << 63).
+ (uint64_t)((exp2 - f64_bias) & 0x07FF); // (1 << 11) - 1.
+ uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) | // (1 << 52) - 1.
+ (exp2_bits << 52) | //
+ (h->negative ? 0x8000000000000000 : 0); // (1 << 63).
wuffs_base__result_f64 ret;
ret.status.repr = NULL;
@@ -2138,7 +2129,7 @@
zero:
do {
- uint64_t bits = h.negative ? 0x8000000000000000 : 0;
+ uint64_t bits = h->negative ? 0x8000000000000000 : 0;
wuffs_base__result_f64 ret;
ret.status.repr = NULL;
@@ -2148,7 +2139,7 @@
infinity:
do {
- uint64_t bits = h.negative ? 0xFFF0000000000000 : 0x7FF0000000000000;
+ uint64_t bits = h->negative ? 0xFFF0000000000000 : 0x7FF0000000000000;
wuffs_base__result_f64 ret;
ret.status.repr = NULL;
@@ -2157,6 +2148,17 @@
} while (0);
}
+WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //
+wuffs_base__parse_number_f64(wuffs_base__slice_u8 s) {
+ wuffs_base__private_implementation__high_prec_dec h;
+ wuffs_base__status status =
+ wuffs_base__private_implementation__high_prec_dec__parse(&h, s);
+ if (status.repr) {
+ return wuffs_base__parse_number_f64_special(s, status.repr);
+ }
+ return wuffs_base__private_implementation__parse_number_f64__fallback(&h);
+}
+
// --------
static inline size_t //
diff --git a/internal/cgen/data/data.go b/internal/cgen/data/data.go
index f29bcd0..dc16614 100644
--- a/internal/cgen/data/data.go
+++ b/internal/cgen/data/data.go
@@ -131,12 +131,12 @@
"" +
"// --------\n\nstatic wuffs_base__result_f64 //\nwuffs_base__parse_number_f64_special(wuffs_base__slice_u8 s,\n const char* fallback_status_repr) {\n do {\n uint8_t* p = s.ptr;\n uint8_t* q = s.ptr + s.len;\n\n for (; (p < q) && (*p == '_'); p++) {\n }\n if (p >= q) {\n goto fallback;\n }\n\n // Parse sign.\n bool negative = false;\n do {\n if (*p == '+') {\n p++;\n } else if (*p == '-') {\n negative = true;\n p++;\n } else {\n break;\n }\n for (; (p < q) && (*p == '_'); p++) {\n }\n } while (0);\n if (p >= q) {\n goto fallback;\n }\n\n bool nan = false;\n switch (p[0]) {\n case 'I':\n case 'i':\n if (((q - p) < 3) || //\n ((p[1] != 'N') && (p[1] != 'n')) || //\n ((p[2] != 'F') && (p[2] != 'f'))) {\n goto fallback;\n }\n p += 3;\n\n if ((p >= q) || (*p == '_')) {\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 fallback;\n }\n p += 5;\n\n if ((p >= q) || (*p == '_')) {\n break;\n }\n goto fallback;\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 fallback;\n }\n p += 3;\n\n if ((p >= q) || (*p == '_')) {\n nan = true;\n break;\n }\n goto fallback;\n\n default:\n goto fallback;\n }\n\n // Finish.\n for (; (p < q) && (*p == '_'); p++) {\n }\n if (p != q) {\n goto fallback;\n }\n wuffs_base__result_f64 ret;\n ret.status.repr = NULL;\n ret.va" +
- "lue = wuffs_base__ieee_754_bit_representation__to_f64(\n (nan ? 0x7FFFFFFFFFFFFFFF : 0x7FF0000000000000) |\n (negative ? 0x8000000000000000 : 0));\n return ret;\n } while (0);\n\nfallback:\n do {\n wuffs_base__result_f64 ret;\n ret.status.repr = fallback_status_repr;\n ret.value = 0;\n return ret;\n } while (0);\n}\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //\nwuffs_base__parse_number_f64(wuffs_base__slice_u8 s) {\n wuffs_base__private_implementation__medium_prec_bin m;\n wuffs_base__private_implementation__high_prec_dec h;\n\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 wuffs_base__status status =\n " +
- " wuffs_base__private_implementation__high_prec_dec__parse(&h, s);\n if (status.repr) {\n return wuffs_base__parse_number_f64_special(s, status.repr);\n }\n\n // Handle 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 wuffs_base__result_f64 mpb_result =\n wuffs_base__private_implementation__medium_prec_bin__parse_number_f64(\n &m, &h, false);\n if (mpb_result.status.repr == NULL) {\n return mpb_result;\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,\n 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_lshif" +
- "t(&h,\n 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__privat" +
- "e_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)((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__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__to_f64(bits);\n return ret;\n } while (0);\n\ninfinity:\n do {\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__to_f64(bits);\n return ret;\n } while (0);\n}\n\n" +
+ "lue = wuffs_base__ieee_754_bit_representation__to_f64(\n (nan ? 0x7FFFFFFFFFFFFFFF : 0x7FF0000000000000) |\n (negative ? 0x8000000000000000 : 0));\n return ret;\n } while (0);\n\nfallback:\n do {\n wuffs_base__result_f64 ret;\n ret.status.repr = fallback_status_repr;\n ret.value = 0;\n return ret;\n } while (0);\n}\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //\nwuffs_base__private_implementation__parse_number_f64__fallback(\n wuffs_base__private_implementation__high_prec_dec* h) {\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 // Handle zero and obvious extremes. The largest and smallest positive\n // f" +
+ "inite 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 wuffs_base__private_implementation__medium_prec_bin m;\n wuffs_base__result_f64 mpb_result =\n wuffs_base__private_implementation__medium_prec_bin__parse_number_f64(\n &m, h, false);\n if (mpb_result.status.repr == NULL) {\n return mpb_result;\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_bas" +
+ "e__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 numbe" +
+ "rs.\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__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__to_f64(bits);\n return ret;\n } while (0);\n\ninfinity:\n do {\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_representatio" +
+ "n__to_f64(bits);\n return ret;\n } while (0);\n}\n\nWUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //\nwuffs_base__parse_number_f64(wuffs_base__slice_u8 s) {\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 if (status.repr) {\n return wuffs_base__parse_number_f64_special(s, status.repr);\n }\n return wuffs_base__private_implementation__parse_number_f64__fallback(&h);\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 86f7417..cf96ec5 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -10953,10 +10953,8 @@
}
WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //
-wuffs_base__parse_number_f64(wuffs_base__slice_u8 s) {
- wuffs_base__private_implementation__medium_prec_bin m;
- wuffs_base__private_implementation__high_prec_dec h;
-
+wuffs_base__private_implementation__parse_number_f64__fallback(
+ wuffs_base__private_implementation__high_prec_dec* h) {
do {
// powers converts decimal powers of 10 to binary powers of 2. For example,
// (10000 >> 13) is 1. It stops before the elements exceed 60, also known
@@ -10967,23 +10965,18 @@
33, 36, 39, 43, 46, 49, 53, 56, 59, //
};
- wuffs_base__status status =
- wuffs_base__private_implementation__high_prec_dec__parse(&h, s);
- if (status.repr) {
- return wuffs_base__parse_number_f64_special(s, status.repr);
- }
-
// Handle zero and obvious extremes. The largest and smallest positive
// finite f64 values are approximately 1.8e+308 and 4.9e-324.
- if ((h.num_digits == 0) || (h.decimal_point < -326)) {
+ if ((h->num_digits == 0) || (h->decimal_point < -326)) {
goto zero;
- } else if (h.decimal_point > 310) {
+ } else if (h->decimal_point > 310) {
goto infinity;
}
+ wuffs_base__private_implementation__medium_prec_bin m;
wuffs_base__result_f64 mpb_result =
wuffs_base__private_implementation__medium_prec_bin__parse_number_f64(
- &m, &h, false);
+ &m, h, false);
if (mpb_result.status.repr == NULL) {
return mpb_result;
}
@@ -10993,39 +10986,37 @@
// far, ending with a value certainly below 1 and possibly below ½...
const int32_t f64_bias = -1023;
int32_t exp2 = 0;
- while (h.decimal_point > 0) {
- uint32_t n = (uint32_t)(+h.decimal_point);
+ while (h->decimal_point > 0) {
+ uint32_t n = (uint32_t)(+h->decimal_point);
uint32_t shift =
(n < num_powers)
? powers[n]
: WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
- wuffs_base__private_implementation__high_prec_dec__small_rshift(&h,
- shift);
- if (h.decimal_point <
+ wuffs_base__private_implementation__high_prec_dec__small_rshift(h, shift);
+ if (h->decimal_point <
-WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
goto zero;
}
exp2 += (int32_t)shift;
}
// ...then we shift left, putting us in [½ .. 1].
- while (h.decimal_point <= 0) {
+ while (h->decimal_point <= 0) {
uint32_t shift;
- if (h.decimal_point == 0) {
- if (h.digits[0] >= 5) {
+ if (h->decimal_point == 0) {
+ if (h->digits[0] >= 5) {
break;
}
- shift = (h.digits[0] <= 2) ? 2 : 1;
+ shift = (h->digits[0] <= 2) ? 2 : 1;
} else {
- uint32_t n = (uint32_t)(-h.decimal_point);
+ uint32_t n = (uint32_t)(-h->decimal_point);
shift = (n < num_powers)
? powers[n]
: WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
}
- wuffs_base__private_implementation__high_prec_dec__small_lshift(&h,
- shift);
- if (h.decimal_point >
+ wuffs_base__private_implementation__high_prec_dec__small_lshift(h, shift);
+ if (h->decimal_point >
+WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
goto infinity;
}
@@ -11041,7 +11032,7 @@
if (n > WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
n = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
}
- wuffs_base__private_implementation__high_prec_dec__small_rshift(&h, n);
+ wuffs_base__private_implementation__high_prec_dec__small_rshift(h, n);
exp2 += (int32_t)n;
}
@@ -11051,9 +11042,9 @@
}
// Extract 53 bits for the mantissa (in base-2).
- wuffs_base__private_implementation__high_prec_dec__small_lshift(&h, 53);
+ wuffs_base__private_implementation__high_prec_dec__small_lshift(h, 53);
uint64_t man2 =
- wuffs_base__private_implementation__high_prec_dec__rounded_integer(&h);
+ wuffs_base__private_implementation__high_prec_dec__rounded_integer(h);
// Rounding might have added one bit. If so, shift and re-check overflow.
if ((man2 >> 53) != 0) {
@@ -11071,10 +11062,10 @@
// Pack the bits and return.
uint64_t exp2_bits =
- (uint64_t)((exp2 - f64_bias) & 0x07FF); // (1 << 11) - 1.
- uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) | // (1 << 52) - 1.
- (exp2_bits << 52) | //
- (h.negative ? 0x8000000000000000 : 0); // (1 << 63).
+ (uint64_t)((exp2 - f64_bias) & 0x07FF); // (1 << 11) - 1.
+ uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) | // (1 << 52) - 1.
+ (exp2_bits << 52) | //
+ (h->negative ? 0x8000000000000000 : 0); // (1 << 63).
wuffs_base__result_f64 ret;
ret.status.repr = NULL;
@@ -11084,7 +11075,7 @@
zero:
do {
- uint64_t bits = h.negative ? 0x8000000000000000 : 0;
+ uint64_t bits = h->negative ? 0x8000000000000000 : 0;
wuffs_base__result_f64 ret;
ret.status.repr = NULL;
@@ -11094,7 +11085,7 @@
infinity:
do {
- uint64_t bits = h.negative ? 0xFFF0000000000000 : 0x7FF0000000000000;
+ uint64_t bits = h->negative ? 0xFFF0000000000000 : 0x7FF0000000000000;
wuffs_base__result_f64 ret;
ret.status.repr = NULL;
@@ -11103,6 +11094,17 @@
} while (0);
}
+WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //
+wuffs_base__parse_number_f64(wuffs_base__slice_u8 s) {
+ wuffs_base__private_implementation__high_prec_dec h;
+ wuffs_base__status status =
+ wuffs_base__private_implementation__high_prec_dec__parse(&h, s);
+ if (status.repr) {
+ return wuffs_base__parse_number_f64_special(s, status.repr);
+ }
+ return wuffs_base__private_implementation__parse_number_f64__fallback(&h);
+}
+
// --------
static inline size_t //