MCPcopy Create free account
hub / github.com/beefytech/Beef / fxp_parse

Function fxp_parse

BeefRT/JEMalloc/src/fxp.c:11–95  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

9}
10
11bool
12fxp_parse(fxp_t *result, const char *str, char **end) {
13 /*
14 * Using malloc_strtoumax in this method isn't as handy as you might
15 * expect (I tried). In the fractional part, significant leading zeros
16 * mean that you still need to do your own parsing, now with trickier
17 * math. In the integer part, the casting (uintmax_t to uint32_t)
18 * forces more reasoning about bounds than just checking for overflow as
19 * we parse.
20 */
21 uint32_t integer_part = 0;
22
23 const char *cur = str;
24
25 /* The string must start with a digit or a decimal point. */
26 if (*cur != '.' && !fxp_isdigit(*cur)) {
27 return true;
28 }
29
30 while ('0' <= *cur && *cur <= '9') {
31 integer_part *= 10;
32 integer_part += *cur - '0';
33 if (integer_part >= (1U << 16)) {
34 return true;
35 }
36 cur++;
37 }
38
39 /*
40 * We've parsed all digits at the beginning of the string, without
41 * overflow. Either we're done, or there's a fractional part.
42 */
43 if (*cur != '.') {
44 *result = (integer_part << 16);
45 if (end != NULL) {
46 *end = (char *)cur;
47 }
48 return false;
49 }
50
51 /* There's a fractional part. */
52 cur++;
53 if (!fxp_isdigit(*cur)) {
54 /* Shouldn't end on the decimal point. */
55 return true;
56 }
57
58 /*
59 * We use a lot of precision for the fractional part, even though we'll
60 * discard most of it; this lets us get exact values for the important
61 * special case where the denominator is a small power of 2 (for
62 * instance, 1/512 == 0.001953125 is exactly representable even with
63 * only 16 bits of fractional precision). We need to left-shift by 16
64 * before dividing so we pick the number of digits to be
65 * floor(log(2**48)) = 14.
66 */
67 uint64_t fractional_part = 0;
68 uint64_t frac_div = 1;

Callers 1

malloc_conf_init_helperFunction · 0.85

Calls 1

fxp_isdigitFunction · 0.85

Tested by

no test coverage detected