kiba-engine
floating.c
1 #include <kiba/format/defaults/floating.h>
2 
3 #include <kiba/format/defaults/string.h>
4 
5 // floating point conversion logic based on ulfjack's ryu
6 
7 #define DOUBLE_POW5_INV_BITCOUNT 125
8 #define DOUBLE_POW5_BITCOUNT 125
9 
10 #define DOUBLE_POW5_INV_TABLE_SIZE 342
11 #define DOUBLE_POW5_TABLE_SIZE 326
12 
13 static const u64 DOUBLE_POW5_INV_SPLIT[DOUBLE_POW5_INV_TABLE_SIZE][2];
14 static const u64 DOUBLE_POW5_SPLIT[DOUBLE_POW5_TABLE_SIZE][2];
15 
16 // Returns e == 0 ? 1 : ceil(log_2(5^e))
17 static inline i32 pow5bits(const i32 e) {
18  // This approximation works up to the point that the multiplication overflows at e = 3529.
19  // If the multiplication were done in 64 bits, it would fail at 5^4004 which is just greater
20  // than 2^9297. TODO investigate this
21  KB_ASSERT(e >= 0, "e must be positive");
22  KB_ASSERT(e <= 3528, "approximation must not be used outside it's bounds");
23  return (i32) (((((u32) e) * 1217359) >> 19) + 1);
24 }
25 
26 static inline u64 umul128(const u64 a, const u64 b, u64 *const productHi) {
27  const u32 aLo = (u32) a;
28  const u32 aHi = (u32) (a >> 32);
29  const u32 bLo = (u32) b;
30  const u32 bHi = (u32) (b >> 32);
31 
32  const u64 b00 = (u64) aLo * bLo;
33  const u64 b01 = (u64) aLo * bHi;
34  const u64 b10 = (u64) aHi * bLo;
35  const u64 b11 = (u64) aHi * bHi;
36 
37  const u32 b00Lo = (u32) b00;
38  const u32 b00Hi = (u32) (b00 >> 32);
39 
40  const u64 mid1 = b10 + b00Hi;
41  const u32 mid1Lo = (u32) (mid1);
42  const u32 mid1Hi = (u32) (mid1 >> 32);
43 
44  const u64 mid2 = b01 + mid1Lo;
45  const u32 mid2Lo = (u32) (mid2);
46  const u32 mid2Hi = (u32) (mid2 >> 32);
47 
48  const u64 pHi = b11 + mid1Hi + mid2Hi;
49  const u64 pLo = ((u64) mid2Lo << 32) | b00Lo;
50 
51  *productHi = pHi;
52  return pLo;
53 }
54 
55 // Returns the lower 64 bits of (hi*2^64 + lo) >> dist, with 0 < dist < 64.
56 static inline u64 shiftright128(const u64 lo, const u64 hi, const u32 dist) {
57  KB_ASSERT(dist >= 2, "dist should be at least 2");
58  // TODO investigate this bound violation, see comment above why this constraint is weird
59  // KB_ASSERT(dist <= 59, "dist should not exceed 59");
60  return (hi << (64 - dist)) | (lo >> dist);
61 }
62 
63 static inline u64 mul_shift64(const u64 m, const u64 *const mul, const i32 j) {
64  // m is maximum 55 bits
65  u64 high1; // 128
66  const u64 low1 = umul128(m, mul[1], &high1); // 64
67  u64 high0; // 64
68  umul128(m, mul[0], &high0); // 0
69  const u64 sum = high0 + low1;
70  if (sum < high0) {
71  ++high1; // overflow into high1
72  }
73  return shiftright128(sum, high1, (u32) j - 64);
74 }
75 
76 static inline u64 mul_shift_all64(const u64 m,
77  const u64 *mul,
78  const i32 j,
79  u64 *const vp,
80  u64 *const vm,
81  const u32 mm_shift) {
82  *vp = mul_shift64(4 * m + 2, mul, j);
83  *vm = mul_shift64(4 * m - 1 - mm_shift, mul, j);
84  return mul_shift64(4 * m, mul, j);
85 }
86 
87 // calculate the power of 5 that is a factor for value
88 static inline u32 pow5factor(u64 value) {
89  // uses modular inverse
90  const u64 m_inv_5 = 14757395258967641293u; // 5 * m_inv_5 = 1 (mod 2^64)
91  const u64 n_div_5 = 3689348814741910323u; // #{ n | n = 0 (mod 2^64) } = 2^64 / 5
92  u32 count = 0;
93  for (;;) {
94  assert(value != 0);
95  value *= m_inv_5;
96  if (value > n_div_5) {
97  break;
98  }
99  ++count;
100  }
101  return count;
102 }
103 
104 // Returns true if value is divisible by 5^p.
105 static inline b8 multiple_of_power_of5(const u64 value, const u32 p) { return pow5factor(value) >= p; }
106 
107 // Returns true if value is divisible by 2^p.
108 static inline b8 multiple_of_power_of2(const u64 value, const u32 p) {
109  assert(value != 0);
110  assert(p < 64);
111  return (value & ((((u64) 1) << p) - 1)) == 0;
112 }
113 
114 // returns floor(log_10(2^e))
115 static inline u32 log10pow2(const i32 e) {
116  KB_ASSERT(e >= 0, "e must be positive");
117  KB_ASSERT(e <= 1650, "approximation must not be used outside it's bounds");
118  return (((u32) e) * 78913) >> 18;
119 }
120 
121 // Returns floor(log_10(5^e)); requires 0 <= e <= 2620.
122 static inline u32 log10pow5(const i32 e) {
123  // The first value this approximation fails for is 5^2621 which is just greater than 10^1832.
124  KB_ASSERT(e >= 0, "e must be positive");
125  KB_ASSERT(e <= 2620, "approximation must not be used outside it's bounds");
126  return (((u32) e) * 732923) >> 20;
127 }
128 
129 static inline i32 floor_log2(const u64 value) { return 63 - __builtin_clzll(value); }
130 
131 static inline i32 log2pow5(const i32 e) {
132  KB_ASSERT(e >= 0, "e must be positive");
133  KB_ASSERT(e <= 3528, "approximation must not be used outside it's bounds");
134  return (i32) (((u32) e * 1217359) >> 19);
135 }
136 
137 #define MANTISSA_LENGTH 52 // TODO, change name and unset after use
138 #define EXPONENT_LENGTH 11
139 #define EXPONENT_BIAS 1023
140 
141 #if 0
142 # define FLOATING_DEBUG_PRINT(...) KB_DEBUG(__VA_ARGS__)
143 #else
144 # define FLOATING_DEBUG_PRINT(...)
145 #endif
146 
147 typedef union {
148  f64 f;
149 
150  struct {
151  u64 mantissa : MANTISSA_LENGTH;
152  u32 exponent : EXPONENT_LENGTH;
153  u8 sign: 1;
154  } parts;
155 } float_cast;
156 
157 // TODO consider small int optimization
158 // TODO investigate performance vs multi-digit lookup-table
159 // TODO precision / fixed point notation?
160 // TODO major code cleanup, especially the serialization / deserialization
161 // TODO separate code / lookup-tables into different files
162 
163 static usize format_read_raw_floating_point(format_buffer *buf, format_options options, f64 *value) {
164  UNUSED(options);
165  float_cast res = {0};
166  if (format_buffer_match_chars(buf, "NaN", 3)) {
167  res.parts.exponent = 0x7FF;
168  res.parts.mantissa = 0x1;
169  *value = res.f;
170  return 3;
171  }
172 
173  char c;
174  usize read_chars = 0;
175  if (format_buffer_peak_char(buf, &c) && c == '-') {
176  format_buffer_advance(buf);
177  res.parts.sign = 1;
178  ++read_chars;
179  }
180  if (format_buffer_match_chars(buf, "Inf", 3)) {
181  res.parts.exponent = 0x7FF;
182  *value = res.f;
183  return 3 + read_chars;
184  }
185 
186  if (!(format_buffer_peak_char(buf, &c) && character_is_decimal(c))) {
187  return 0;
188  }
189  format_buffer_advance(buf);
190  ++read_chars;
191  usize pre_dot = 0;
192  u64 m10 = (u64) c - '0';
193  while (format_buffer_peak_char(buf, &c)) {
194  if (character_is_decimal(c)) {
195  format_buffer_advance(buf);
196  u64 digit = (u64) c - '0';
197  m10 = m10 * 10 + digit;
198  ++read_chars;
199  } else if (c == '.') {
200  // TODO handle malformed input with multiple dots
201  pre_dot = read_chars++;
202  format_buffer_advance(buf);
203  } else {
204  break;
205  }
206  }
207  while (format_buffer_peak_char(buf, &c) && character_is_decimal(c)) {
208  format_buffer_advance(buf);
209  u64 digit = (u64) c - '0';
210  m10 = m10 * 10 + digit;
211  ++read_chars;
212  }
213  const i32 post_dot = pre_dot ? (i32) (read_chars - pre_dot - 1) : 0;
214 
215  if (c != 'e' || !(format_buffer_advance(buf) && format_buffer_peak_char(buf, &c))) {
216  return 0;
217  }
218  ++read_chars;
219  i32 factor = 1;
220  if (c == '-') {
221  factor = -1;
222  ++read_chars;
223  if (!(format_buffer_advance(buf) && format_buffer_peak_char(buf, &c))) {
224  return 0;
225  }
226  }
227  if (!character_is_decimal(c)) {
228  return 0;
229  }
230  i32 e10 = factor * ((i32) c - '0');
231  format_buffer_advance(buf);
232  ++read_chars;
233  while (format_buffer_peak_char(buf, &c) && character_is_decimal(c)) {
234  format_buffer_advance(buf);
235  i32 digit = (i32) c - '0';
236  e10 = e10 * 10 + digit;
237  ++read_chars;
238  }
239  e10 -= post_dot;
240 
241  // TODO range checks
242  if (m10 == 0) {
243  // TODO m10_digits + e10 <= -324 -> basically 0
244  *value = res.f;
245  return read_chars;
246  }
247  // TODO m10_digits + e10 >= 310 -> basically infinity
248  FLOATING_DEBUG_PRINT("m10 * 10^e10 = {u64} * 10^{i32}", m10, e10);
249  i32 e2;
250  u64 m2;
251  b8 trailing_zeros;
252  if (e10 >= 0) {
253  e2 = floor_log2(m10) + e10 + log2pow5(e10) - (MANTISSA_LENGTH + 1);
254  i32 j = e2 - e10 - log2pow5(e10) - 1 + DOUBLE_POW5_BITCOUNT;
255  KB_ASSERT(j >= 0, "j must be positive");
256  KB_ASSERT(e10 < DOUBLE_POW5_TABLE_SIZE, "e10 must not exceed lookup table size");
257  m2 = mul_shift64(m10, DOUBLE_POW5_SPLIT[e10], j);
258  trailing_zeros = e2 < e10 || (e2 - e10 < 64 && multiple_of_power_of2(m10, (u32) (e2 - e10)));
259  } else {
260  e2 = floor_log2(m10) + e10 - log2pow5(-e10) - 1 - (MANTISSA_LENGTH + 1);
261  int j = e2 - e10 + log2pow5(-e10) + DOUBLE_POW5_INV_BITCOUNT;
262  KB_ASSERT(-e10 < DOUBLE_POW5_INV_TABLE_SIZE, "-e10 must not exceed lookup table size");
263  m2 = mul_shift64(m10, DOUBLE_POW5_INV_SPLIT[-e10], j);
264  trailing_zeros = multiple_of_power_of5(m10, (u32) -e10);
265  }
266  FLOATING_DEBUG_PRINT("m2 * 10^e2 = {u64} * 2^{i32}", m2, e2);
267 
268  u32 ieee_e2 = (u32) KB_MAX(0, e2 + EXPONENT_BIAS + floor_log2(m2));
269  // TODO if greater than 0x7FF, return inf
270  i32 shift = (i32) (ieee_e2 == 0 ? 1 : ieee_e2) - e2 - EXPONENT_BIAS - MANTISSA_LENGTH;
271  KB_ASSERT(shift >= 0, "shift must be positive");
272  trailing_zeros &= (m2 & ((1ull << (shift - 1)) - 1)) == 0;
273  u64 last_removed_bit = (m2 >> (shift - 1)) & 1;
274  b8 round_up = (last_removed_bit != 0) && (!trailing_zeros || (((m2 >> shift) & 1) != 0));
275  u64 ieee_m2 = (m2 >> shift) + round_up;
276  KB_ASSERT(ieee_m2 <= (1ull << (MANTISSA_LENGTH + 1)), "mantissa must fit into designated number of bits");
277  if (ieee_m2 == 0 && round_up) {
278  ++ieee_e2;
279  }
280 
281  FLOATING_DEBUG_PRINT("ieee e2: {i32}", ieee_e2);
282  FLOATING_DEBUG_PRINT("shift: {i32}", shift);
283  FLOATING_DEBUG_PRINT("round up: {i32}", round_up);
284  FLOATING_DEBUG_PRINT("ieee m2: {u64}", ieee_m2);
285 
286  res.parts.mantissa = ieee_m2 & ((1ull << MANTISSA_LENGTH) - 1);
287  res.parts.exponent = ieee_e2 & 0x7FF;
288  *value = res.f;
289  return read_chars;
290 }
291 
292 b8 format_read_floating_point(format_buffer *buf, format_options options, f64 *value) {
293  usize left_pad_length = 0;
294  while (format_buffer_match_char(buf, FORMAT_PADDING_CHAR)) {
295  ++left_pad_length;
296  }
297 
298  usize read_chars = format_read_raw_floating_point(buf, options, value);
299  if (read_chars == 0) {
300  return false;
301  }
302 
303  usize left_pad, right_pad;
304  format_calculate_padding(options, read_chars, &left_pad, &right_pad);
305  usize i = 0;
306  for (; i < right_pad && format_buffer_match_char(buf, FORMAT_PADDING_CHAR); ++i)
307  ;
308  return left_pad_length == left_pad && i == right_pad;
309 }
310 
311 static inline u32 decimal_length_17(const u64 v) {
312  KB_ASSERT(v < 100000000000000000L, "value must not exceed valid range");
313  if (v >= 10000000000000000L)
314  return 17;
315  if (v >= 1000000000000000L)
316  return 16;
317  if (v >= 100000000000000L)
318  return 15;
319  if (v >= 10000000000000L)
320  return 14;
321  if (v >= 1000000000000L)
322  return 13;
323  if (v >= 100000000000L)
324  return 12;
325  if (v >= 10000000000L)
326  return 11;
327  if (v >= 1000000000L)
328  return 10;
329  if (v >= 100000000L)
330  return 9;
331  if (v >= 10000000L)
332  return 8;
333  if (v >= 1000000L)
334  return 7;
335  if (v >= 100000L)
336  return 6;
337  if (v >= 10000L)
338  return 5;
339  if (v >= 1000L)
340  return 4;
341  if (v >= 100L)
342  return 3;
343  if (v >= 10L)
344  return 2;
345  return 1;
346 }
347 
348 b8 format_write_floating_point(format_buffer *buf, format_options options, f64 value) {
349  FLOATING_DEBUG_PRINT("- Step 1: decode the number");
350  float_cast cast;
351  cast.f = value;
352  FLOATING_DEBUG_PRINT(" raw mantissa: {i64}", (i64) cast.parts.mantissa);
353  FLOATING_DEBUG_PRINT(" raw exponent: {i32}", cast.parts.exponent);
354  FLOATING_DEBUG_PRINT(" raw sign bit: {i32}", cast.parts.sign);
355 
356  // handle the special cases
357  if (cast.parts.exponent == 0x7FF) {
358  if (cast.parts.mantissa == 0) {
359  const char *infs[] = {"Inf", "-Inf"};
360  return format_buffer_add_chars(buf, infs[cast.parts.sign], 3 + cast.parts.sign);
361  }
362  return format_buffer_add_chars(buf, "NaN", 3);
363  }
364  if (cast.parts.exponent == 0 && cast.parts.exponent == 0) {
365  const char *zeros[] = {"0e0", "-0e0"};
366  return format_buffer_add_chars(buf, zeros[cast.parts.sign], 3 + cast.parts.sign);
367  }
368 
369  // bring mantissa and exponent into the form f = (-1)^sign * m2 * 2^e2
370  i32 e2;
371  u64 m2;
372  // both paths will subtract:
373  // - the length of the mantissa from the exponent to move the dot
374  // in the mantissa all the way to the right
375  // - 2 to give the bounds calculation two extra bits. this ensures
376  // that all possible values in this calculation are integers
377  if (cast.parts.exponent == 0) {
378  // raw bits are in denormalized form
379  // -> implicit leading mantissa bit is 0
380  // true exponent is 1 - bias
381  e2 = 1 - EXPONENT_BIAS - MANTISSA_LENGTH - 2;
382  m2 = cast.parts.mantissa;
383  } else {
384  // raw bits are in normalized form
385  // -> implicit leading mantissa bit is 1
386  // true exponent is e - bias
387  e2 = (i32) cast.parts.exponent - EXPONENT_BIAS - MANTISSA_LENGTH - 2;
388  m2 = KB_UBIT(MANTISSA_LENGTH) | cast.parts.mantissa; // add implicit bit
389  }
390  FLOATING_DEBUG_PRINT(" intermediate m2: {u64}", m2);
391  FLOATING_DEBUG_PRINT(" intermediate e2: {i32}", e2 + 2); // account for our bounds preparation
392 
393  // Step 2 determine interval of valid decimal representations
394  FLOATING_DEBUG_PRINT("- Step 2: determine inverval of information preserving outputs");
395  // f = m2 * 2^(e2 + 2)
396  // -> next higher value is at f+ = (m2 + 1) * 2^(e2 + 2)
397  // -> halfway point is (f + f+) / 2 = (2 * m2 + 1) * 2^(e2 + 1)
398  // -> = (4 * m2 + 2) * 2^e2
399  // -> next lower value is at f- = (m2 - 1) * 2^(e2 + 2)
400  // -> = (4 * m2 - 2) * 2^e2
401  // special case: mantissa = (0..0)2 and exponent > 1, then next smallest is
402  // mantissa = (1..1)2 and exponent minus 1
403  // so in this case it should be (4 * m2 - 1) * 2^e2
404  const u64 mv = 4 * m2;
405  const u32 mm_shift = cast.parts.mantissa != 0 || cast.parts.exponent <= 1;
406  FLOATING_DEBUG_PRINT(" boundary base mv: {u64}", mv);
407  FLOATING_DEBUG_PRINT(" boundary shift: {u32}", mm_shift);
408 
409  FLOATING_DEBUG_PRINT("- Step 3: convert to decimal power base");
410  u64 vr, vp, vm;
411  i32 e10;
412  b8 vm_trailing_zeros = false;
413  b8 vr_trailing_zeros = false;
414  const b8 accept_bounds = (m2 & 1) == 0;
415  if (e2 >= 0) {
416  // q = max(0, floor(e2 * log10(2)) - 1)
417  // -> log10(2) is ~0.3
418  // -> will be 0 for 1, 2 and 3
419  // 4 * log10(2) = 1
420  // -> subtract 1 for e2 >= 4
421  // -> remove max
422  // k = B0 + floor(log2(5)^q)
423  // i = -e2 + q + k
424  // -> (aq, bq, cq) = floor( ((u, v, w) * LOOKUP_TABLE_GTE[q]) / 2^(-e2 + q + k) )
425  // (za, zb, zc) = (u % 5^q == 0, v % 5^(q - 1) == 0, w % 5^q == 0)
426  const u32 q = log10pow2(e2) - (e2 > 3);
427  e10 = (i32) q;
428  const i32 k = DOUBLE_POW5_INV_BITCOUNT + pow5bits((i32) q) - 1;
429  const i32 i = -e2 + (i32) q + k;
430  vr = mul_shift_all64(m2, DOUBLE_POW5_INV_SPLIT[q], i, &vp, &vm, mm_shift);
431  FLOATING_DEBUG_PRINT(" {u64} * 2^{i32} / 10^{u32}", mv, e2, q);
432  FLOATING_DEBUG_PRINT(" V+={u64}", vp);
433  FLOATING_DEBUG_PRINT(" V ={u64}", vr);
434  FLOATING_DEBUG_PRINT(" V-={u64}", vm);
435  if (q <= 22) {
436  // Only one of mp, mv, and mm can be a multiple of 5, if any.
437  if ((u32) mv % 5 == 0) {
438  vr_trailing_zeros = multiple_of_power_of5(mv, q);
439  } else if (accept_bounds) {
440  // Same as min(e2 + (~mm & 1), pow5Factor(mm)) >= q
441  // <=> e2 + (~mm & 1) >= q && pow5Factor(mm) >= q
442  // <=> true && pow5Factor(mm) >= q, since e2 >= q.
443  vm_trailing_zeros = multiple_of_power_of5(mv - 1 - mm_shift, q);
444  } else {
445  // Same as min(e2 + 1, pow5Factor(mp)) >= q.
446  vp -= multiple_of_power_of5(mv + 2, q);
447  }
448  }
449  } else {
450  // q = max(0, floor(-e2 * log5(2)) - 1)
451  // -> log5(2) is ~0.43 TODO check logarithm rules how we get from above to the code below
452  // k = ceil(log2(5^q)) - B1
453  // i = -e2 - q
454  // -> (aq, bq, cq) = floor( ((u, v, w) * LOOKUP_TABLE_LT[-e2 - q]) / 2^(q - k) )
455  // (za, zb, zc) = (u % 5^q == 0, v % 5^(q - 1) == 0, w % 5^q == 0)
456  const u32 q = log10pow5(-e2) - (-e2 > 1);
457  e10 = (i32) q + e2;
458  const i32 i = -e2 - (i32) q;
459  const i32 k = pow5bits(i) - DOUBLE_POW5_BITCOUNT;
460  const i32 j = (i32) q - k;
461  vr = mul_shift_all64(m2, DOUBLE_POW5_SPLIT[i], j, &vp, &vm, mm_shift);
462  FLOATING_DEBUG_PRINT(" {u64} * 5^{i32} / 10^{u32}", mv, -e2, q);
463  FLOATING_DEBUG_PRINT(" q={u32} i={i32} k={i32} j={i32}", q, i, k, j);
464  FLOATING_DEBUG_PRINT(" V+={u64}", vp);
465  FLOATING_DEBUG_PRINT(" V ={u64}", vr);
466  FLOATING_DEBUG_PRINT(" V-={u64}", vm);
467  if (q <= 1) {
468  // {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q trailing 0 bits.
469  // mv = 4 * m2, so it always has at least two trailing 0 bits.
470  vr_trailing_zeros = true;
471  if (accept_bounds) {
472  // mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff mm_shift == 1.
473  vm_trailing_zeros = mm_shift == 1;
474  } else {
475  // mp = mv + 2, so it always has at least one trailing 0 bit.
476  --vp;
477  }
478  } else if (q < 63) { // TODO(ulfjack): Use a tighter bound here.
479  // We want to know if the full product has at least q trailing zeros.
480  // We need to compute min(p2(mv), p5(mv) - e2) >= q
481  // <=> p2(mv) >= q && p5(mv) - e2 >= q
482  // <=> p2(mv) >= q (because -e2 >= q)
483  vr_trailing_zeros = multiple_of_power_of2(mv, q);
484  }
485  }
486  FLOATING_DEBUG_PRINT(" converted e10={i32}", e10);
487  FLOATING_DEBUG_PRINT(" converted V+={u64}", vp);
488  FLOATING_DEBUG_PRINT(" converted V ={u64}", vr);
489  FLOATING_DEBUG_PRINT(" converted V-={u64}", vm);
490  FLOATING_DEBUG_PRINT(" converted vm is trailing zeros={raw_string}", vm_trailing_zeros ? "true" : "false");
491  FLOATING_DEBUG_PRINT(" converted vr is trailing zeros={raw_string}", vr_trailing_zeros ? "true" : "false");
492 
493  FLOATING_DEBUG_PRINT("- Step 4: find the shortest decimal representation in the interval of valid representations");
494  i32 removed = 0;
495  u8 last_removed_digit = 0;
496  u64 output;
497  // On average, we remove ~2 digits.
498  if (vm_trailing_zeros || vr_trailing_zeros) {
499  // General case, which happens rarely (~0.7%).
500  for (;;) {
501  const u64 vp_div10 = vp / 10;
502  const u64 vm_div10 = vm / 10;
503  if (vp_div10 <= vm_div10) {
504  break;
505  }
506  // could be replaced with mod operator but as we need the div
507  // result above, this is fine
508  const u32 vm_mod10 = ((u32) vm) - 10 * ((u32) vm_div10);
509  const u64 vr_div10 = vr / 10;
510  const u32 vr_mod10 = ((u32) vr) - 10 * ((u32) vr_div10);
511  vm_trailing_zeros &= vm_mod10 == 0;
512  vr_trailing_zeros &= last_removed_digit == 0;
513  last_removed_digit = (u8) vr_mod10;
514  vr = vr_div10;
515  vp = vp_div10;
516  vm = vm_div10;
517  ++removed;
518  }
519  FLOATING_DEBUG_PRINT(" rare case V+={u64}", vp);
520  FLOATING_DEBUG_PRINT(" rare case V ={u64}", vr);
521  FLOATING_DEBUG_PRINT(" rare case V-={u64}", vm);
522  FLOATING_DEBUG_PRINT(" rare case d-10={raw_string}", vm_trailing_zeros ? "true" : "false");
523  if (vm_trailing_zeros) {
524  for (;;) {
525  const u64 vm_div10 = vm / 10;
526  const u32 vm_mod10 = ((u32) vm) - 10 * ((u32) vm_div10);
527  if (vm_mod10 != 0) {
528  break;
529  }
530  const u64 vp_div10 = vp / 10;
531  const u64 vr_div10 = vr / 10;
532  const u32 vr_mod10 = ((u32) vr) - 10 * ((u32) vr_div10);
533  vr_trailing_zeros &= last_removed_digit == 0;
534  last_removed_digit = (u8) vr_mod10;
535  vr = vr_div10;
536  vp = vp_div10;
537  vm = vm_div10;
538  ++removed;
539  }
540  }
541  FLOATING_DEBUG_PRINT(" rare case vp={u64}", vp);
542  FLOATING_DEBUG_PRINT(" rare case vr={u64}", vr);
543  FLOATING_DEBUG_PRINT(" rare case vm={u64}", vm);
544  FLOATING_DEBUG_PRINT(" rare case last_removed_digit={i32}", last_removed_digit);
545  FLOATING_DEBUG_PRINT(" rare case vr is trailing zeros={raw_string}", vr_trailing_zeros ? "true" : "false");
546  if (vr_trailing_zeros && last_removed_digit == 5 && vr % 2 == 0) {
547  // Round even if the exact number is .....50..0.
548  last_removed_digit = 4;
549  }
550  // We need to take vr + 1 if vr is outside bounds or we need to round up.
551  output = vr + ((vr == vm && (!accept_bounds || !vm_trailing_zeros)) || last_removed_digit >= 5);
552  } else {
553  // Specialized for the common case (~99.3%). Percentages below are relative to this.
554  b8 round_up = false;
555  const u64 vp_div100 = vp / 100;
556  const u64 vm_div100 = vm / 100;
557  if (vp_div100 > vm_div100) { // Optimization: remove two digits at a time (~86.2%).
558  const u64 vr_div100 = vr / 100;
559  const u32 vr_mod100 = (u32) vr - 100 * (u32) vr_div100;
560  round_up = vr_mod100 >= 50;
561  vr = vr_div100;
562  vp = vp_div100;
563  vm = vm_div100;
564  removed += 2;
565  }
566  // Loop iterations below (approximately), without optimization above:
567  // 0: 0.03%, 1: 13.8%, 2: 70.6%, 3: 14.0%, 4: 1.40%, 5: 0.14%, 6+: 0.02%
568  // Loop iterations below (approximately), with optimization above:
569  // 0: 70.6%, 1: 27.8%, 2: 1.40%, 3: 0.14%, 4+: 0.02%
570  for (;;) {
571  const u64 vp_div10 = vp / 10;
572  const u64 vm_div10 = vm / 10;
573  if (vp_div10 <= vm_div10) {
574  break;
575  }
576  const u64 vr_div10 = vr / 10;
577  const u32 vr_mod10 = (u32) vr - 10 * (u32) vr_div10;
578  round_up = vr_mod10 >= 5;
579  vr = vr_div10;
580  vp = vp_div10;
581  vm = vm_div10;
582  ++removed;
583  }
584  FLOATING_DEBUG_PRINT(" common case vp={u64}", vp);
585  FLOATING_DEBUG_PRINT(" common case vr={u64}", vr);
586  FLOATING_DEBUG_PRINT(" common case vm={u64}", vm);
587  FLOATING_DEBUG_PRINT(" common case round_up={raw_string}", round_up ? "true" : "false");
588  FLOATING_DEBUG_PRINT(" common case vr is trailing zeros={raw_string}", vr_trailing_zeros ? "true" : "false");
589  // We need to take vr + 1 if vr is outside bounds or we need to round up.
590  output = vr + (vr == vm || round_up);
591  }
592  FLOATING_DEBUG_PRINT("- Done");
593  FLOATING_DEBUG_PRINT("final e10={i32}", e10);
594  FLOATING_DEBUG_PRINT("final removed={i32}", removed);
595  i32 exp = e10 + removed;
596 
597  FLOATING_DEBUG_PRINT("final V+={u64}", vp);
598  FLOATING_DEBUG_PRINT("final V ={u64}", vr);
599  FLOATING_DEBUG_PRINT("final V-={u64}", vm);
600  FLOATING_DEBUG_PRINT("final O={u64}", output);
601  FLOATING_DEBUG_PRINT("final EXP={i32}", exp);
602 
603  char res_str[32] = {0};
604  u32 index = 0;
605  if (cast.parts.sign) {
606  res_str[index++] = '-';
607  }
608  u32 output_length = decimal_length_17(output);
609  for (u32 i = 0; i < output_length - 1; ++i) {
610  const u64 c = output % 10;
611  output /= 10;
612  res_str[index + output_length - i] = (char) ('0' + c);
613  }
614  res_str[index] = (char) ('0' + output % 10);
615  if (output_length > 1) {
616  res_str[index + 1] = '.';
617  index += output_length;
618  }
619  ++index;
620 
621  exp += (i32) output_length - 1;
622  res_str[index++] = 'e';
623  if (exp < 0) {
624  res_str[index++] = '-';
625  exp = -exp;
626  }
627  usize index_offset = 1;
628  if (exp >= 100) {
629  const u32 c = (u32) exp % 10;
630  exp /= 10;
631  res_str[index + 2] = (char) ('0' + c);
632  ++index_offset;
633  }
634  if (exp >= 10) {
635  const u32 c = (u32) exp % 10;
636  exp /= 10;
637  res_str[index + 1] = (char) ('0' + c);
638  ++index_offset;
639  }
640  {
641  const u32 c = (u32) exp % 10;
642  exp /= 10;
643  res_str[index] = (char) ('0' + c);
644  }
645  return format_write_character_array(buf,
646  options,
647  string_view_from_string(string_from_raw_n(res_str, index + index_offset)));
648 }
649 
650 FORMAT_FUNCTION(format_read_f64) {
651  f64 *arg = VA_ARG(*args, f64 *);
652  return format_read_floating_point(buf, options, arg);
653 }
654 
655 FORMAT_FUNCTION(format_write_f64) {
656  f64 arg = VA_ARG(*args, f64);
657  return format_write_floating_point(buf, options, arg);
658 }
659 
660 FORMAT_FUNCTION(format_read_f32) {
661  f32 *arg = VA_ARG(*args, f32 *);
662  f64 tmp;
663  if (!format_read_floating_point(buf, options, &tmp)) {
664  return false;
665  }
666  *arg = (f32) tmp;
667  return true;
668 }
669 
670 FORMAT_FUNCTION(format_write_f32) { return format_write_f64(buf, options, args); }
671 
672 static const u64 DOUBLE_POW5_INV_SPLIT[DOUBLE_POW5_INV_TABLE_SIZE][2] = {
673  { 1u, 2305843009213693952u},
674  {11068046444225730970u, 1844674407370955161u},
675  { 5165088340638674453u, 1475739525896764129u},
676  { 7821419487252849886u, 1180591620717411303u},
677  { 8824922364862649494u, 1888946593147858085u},
678  { 7059937891890119595u, 1511157274518286468u},
679  {13026647942995916322u, 1208925819614629174u},
680  { 9774590264567735146u, 1934281311383406679u},
681  {11509021026396098440u, 1547425049106725343u},
682  {16585914450600699399u, 1237940039285380274u},
683  {15469416676735388068u, 1980704062856608439u},
684  {16064882156130220778u, 1584563250285286751u},
685  { 9162556910162266299u, 1267650600228229401u},
686  { 7281393426775805432u, 2028240960365167042u},
687  {16893161185646375315u, 1622592768292133633u},
688  { 2446482504291369283u, 1298074214633706907u},
689  { 7603720821608101175u, 2076918743413931051u},
690  { 2393627842544570617u, 1661534994731144841u},
691  {16672297533003297786u, 1329227995784915872u},
692  {11918280793837635165u, 2126764793255865396u},
693  { 5845275820328197809u, 1701411834604692317u},
694  {15744267100488289217u, 1361129467683753853u},
695  { 3054734472329800808u, 2177807148294006166u},
696  {17201182836831481939u, 1742245718635204932u},
697  { 6382248639981364905u, 1393796574908163946u},
698  { 2832900194486363201u, 2230074519853062314u},
699  { 5955668970331000884u, 1784059615882449851u},
700  { 1075186361522890384u, 1427247692705959881u},
701  {12788344622662355584u, 2283596308329535809u},
702  {13920024512871794791u, 1826877046663628647u},
703  { 3757321980813615186u, 1461501637330902918u},
704  {10384555214134712795u, 1169201309864722334u},
705  { 5547241898389809503u, 1870722095783555735u},
706  { 4437793518711847602u, 1496577676626844588u},
707  {10928932444453298728u, 1197262141301475670u},
708  {17486291911125277965u, 1915619426082361072u},
709  { 6610335899416401726u, 1532495540865888858u},
710  {12666966349016942027u, 1225996432692711086u},
711  {12888448528943286597u, 1961594292308337738u},
712  {17689456452638449924u, 1569275433846670190u},
713  {14151565162110759939u, 1255420347077336152u},
714  { 7885109000409574610u, 2008672555323737844u},
715  { 9997436015069570011u, 1606938044258990275u},
716  { 7997948812055656009u, 1285550435407192220u},
717  {12796718099289049614u, 2056880696651507552u},
718  { 2858676849947419045u, 1645504557321206042u},
719  {13354987924183666206u, 1316403645856964833u},
720  {17678631863951955605u, 2106245833371143733u},
721  { 3074859046935833515u, 1684996666696914987u},
722  {13527933681774397782u, 1347997333357531989u},
723  {10576647446613305481u, 2156795733372051183u},
724  {15840015586774465031u, 1725436586697640946u},
725  { 8982663654677661702u, 1380349269358112757u},
726  {18061610662226169046u, 2208558830972980411u},
727  {10759939715039024913u, 1766847064778384329u},
728  {12297300586773130254u, 1413477651822707463u},
729  {15986332124095098083u, 2261564242916331941u},
730  { 9099716884534168143u, 1809251394333065553u},
731  {14658471137111155161u, 1447401115466452442u},
732  { 4348079280205103483u, 1157920892373161954u},
733  {14335624477811986218u, 1852673427797059126u},
734  { 7779150767507678651u, 1482138742237647301u},
735  { 2533971799264232598u, 1185710993790117841u},
736  {15122401323048503126u, 1897137590064188545u},
737  {12097921058438802501u, 1517710072051350836u},
738  { 5988988032009131678u, 1214168057641080669u},
739  {16961078480698431330u, 1942668892225729070u},
740  {13568862784558745064u, 1554135113780583256u},
741  { 7165741412905085728u, 1243308091024466605u},
742  {11465186260648137165u, 1989292945639146568u},
743  {16550846638002330379u, 1591434356511317254u},
744  {16930026125143774626u, 1273147485209053803u},
745  { 4951948911778577463u, 2037035976334486086u},
746  { 272210314680951647u, 1629628781067588869u},
747  { 3907117066486671641u, 1303703024854071095u},
748  { 6251387306378674625u, 2085924839766513752u},
749  {16069156289328670670u, 1668739871813211001u},
750  { 9165976216721026213u, 1334991897450568801u},
751  { 7286864317269821294u, 2135987035920910082u},
752  {16897537898041588005u, 1708789628736728065u},
753  {13518030318433270404u, 1367031702989382452u},
754  { 6871453250525591353u, 2187250724783011924u},
755  { 9186511415162383406u, 1749800579826409539u},
756  {11038557946871817048u, 1399840463861127631u},
757  {10282995085511086630u, 2239744742177804210u},
758  { 8226396068408869304u, 1791795793742243368u},
759  {13959814484210916090u, 1433436634993794694u},
760  {11267656730511734774u, 2293498615990071511u},
761  { 5324776569667477496u, 1834798892792057209u},
762  { 7949170070475892320u, 1467839114233645767u},
763  {17427382500606444826u, 1174271291386916613u},
764  { 5747719112518849781u, 1878834066219066582u},
765  {15666221734240810795u, 1503067252975253265u},
766  {12532977387392648636u, 1202453802380202612u},
767  { 5295368560860596524u, 1923926083808324180u},
768  { 4236294848688477220u, 1539140867046659344u},
769  { 7078384693692692099u, 1231312693637327475u},
770  {11325415509908307358u, 1970100309819723960u},
771  { 9060332407926645887u, 1576080247855779168u},
772  {14626963555825137356u, 1260864198284623334u},
773  {12335095245094488799u, 2017382717255397335u},
774  { 9868076196075591040u, 1613906173804317868u},
775  {15273158586344293478u, 1291124939043454294u},
776  {13369007293925138595u, 2065799902469526871u},
777  { 7005857020398200553u, 1652639921975621497u},
778  {16672732060544291412u, 1322111937580497197u},
779  {11918976037903224966u, 2115379100128795516u},
780  { 5845832015580669650u, 1692303280103036413u},
781  {12055363241948356366u, 1353842624082429130u},
782  { 841837113407818570u, 2166148198531886609u},
783  { 4362818505468165179u, 1732918558825509287u},
784  {14558301248600263113u, 1386334847060407429u},
785  {12225235553534690011u, 2218135755296651887u},
786  { 2401490813343931363u, 1774508604237321510u},
787  { 1921192650675145090u, 1419606883389857208u},
788  {17831303500047873437u, 2271371013423771532u},
789  { 6886345170554478103u, 1817096810739017226u},
790  { 1819727321701672159u, 1453677448591213781u},
791  {16213177116328979020u, 1162941958872971024u},
792  {14873036941900635463u, 1860707134196753639u},
793  {15587778368262418694u, 1488565707357402911u},
794  { 8780873879868024632u, 1190852565885922329u},
795  { 2981351763563108441u, 1905364105417475727u},
796  {13453127855076217722u, 1524291284333980581u},
797  { 7073153469319063855u, 1219433027467184465u},
798  {11317045550910502167u, 1951092843947495144u},
799  {12742985255470312057u, 1560874275157996115u},
800  {10194388204376249646u, 1248699420126396892u},
801  { 1553625868034358140u, 1997919072202235028u},
802  { 8621598323911307159u, 1598335257761788022u},
803  {17965325103354776697u, 1278668206209430417u},
804  {13987124906400001422u, 2045869129935088668u},
805  { 121653480894270168u, 1636695303948070935u},
806  { 97322784715416134u, 1309356243158456748u},
807  {14913111714512307107u, 2094969989053530796u},
808  { 8241140556867935363u, 1675975991242824637u},
809  {17660958889720079260u, 1340780792994259709u},
810  {17189487779326395846u, 2145249268790815535u},
811  {13751590223461116677u, 1716199415032652428u},
812  {18379969808252713988u, 1372959532026121942u},
813  {14650556434236701088u, 2196735251241795108u},
814  { 652398703163629901u, 1757388200993436087u},
815  {11589965406756634890u, 1405910560794748869u},
816  { 7475898206584884855u, 2249456897271598191u},
817  { 2291369750525997561u, 1799565517817278553u},
818  { 9211793429904618695u, 1439652414253822842u},
819  {18428218302589300235u, 2303443862806116547u},
820  { 7363877012587619542u, 1842755090244893238u},
821  {13269799239553916280u, 1474204072195914590u},
822  {10615839391643133024u, 1179363257756731672u},
823  { 2227947767661371545u, 1886981212410770676u},
824  {16539753473096738529u, 1509584969928616540u},
825  {13231802778477390823u, 1207667975942893232u},
826  { 6413489186596184024u, 1932268761508629172u},
827  {16198837793502678189u, 1545815009206903337u},
828  { 5580372605318321905u, 1236652007365522670u},
829  { 8928596168509315048u, 1978643211784836272u},
830  {18210923379033183008u, 1582914569427869017u},
831  { 7190041073742725760u, 1266331655542295214u},
832  { 436019273762630246u, 2026130648867672343u},
833  { 7727513048493924843u, 1620904519094137874u},
834  { 9871359253537050198u, 1296723615275310299u},
835  { 4726128361433549347u, 2074757784440496479u},
836  { 7470251503888749801u, 1659806227552397183u},
837  {13354898832594820487u, 1327844982041917746u},
838  {13989140502667892133u, 2124551971267068394u},
839  {14880661216876224029u, 1699641577013654715u},
840  {11904528973500979224u, 1359713261610923772u},
841  { 4289851098633925465u, 2175541218577478036u},
842  {18189276137874781665u, 1740432974861982428u},
843  { 3483374466074094362u, 1392346379889585943u},
844  { 1884050330976640656u, 2227754207823337509u},
845  { 5196589079523222848u, 1782203366258670007u},
846  {15225317707844309248u, 1425762693006936005u},
847  { 5913764258841343181u, 2281220308811097609u},
848  { 8420360221814984868u, 1824976247048878087u},
849  {17804334621677718864u, 1459980997639102469u},
850  {17932816512084085415u, 1167984798111281975u},
851  {10245762345624985047u, 1868775676978051161u},
852  { 4507261061758077715u, 1495020541582440929u},
853  { 7295157664148372495u, 1196016433265952743u},
854  { 7982903447895485668u, 1913626293225524389u},
855  {10075671573058298858u, 1530901034580419511u},
856  { 4371188443704728763u, 1224720827664335609u},
857  {14372599139411386667u, 1959553324262936974u},
858  {15187428126271019657u, 1567642659410349579u},
859  {15839291315758726049u, 1254114127528279663u},
860  { 3206773216762499739u, 2006582604045247462u},
861  {13633465017635730761u, 1605266083236197969u},
862  {14596120828850494932u, 1284212866588958375u},
863  { 4907049252451240275u, 2054740586542333401u},
864  { 236290587219081897u, 1643792469233866721u},
865  {14946427728742906810u, 1315033975387093376u},
866  {16535586736504830250u, 2104054360619349402u},
867  { 5849771759720043554u, 1683243488495479522u},
868  {15747863852001765813u, 1346594790796383617u},
869  {10439186904235184007u, 2154551665274213788u},
870  {15730047152871967852u, 1723641332219371030u},
871  {12584037722297574282u, 1378913065775496824u},
872  { 9066413911450387881u, 2206260905240794919u},
873  {10942479943902220628u, 1765008724192635935u},
874  { 8753983955121776503u, 1412006979354108748u},
875  {10317025513452932081u, 2259211166966573997u},
876  { 874922781278525018u, 1807368933573259198u},
877  { 8078635854506640661u, 1445895146858607358u},
878  {13841606313089133175u, 1156716117486885886u},
879  {14767872471458792434u, 1850745787979017418u},
880  { 746251532941302978u, 1480596630383213935u},
881  { 597001226353042382u, 1184477304306571148u},
882  {15712597221132509104u, 1895163686890513836u},
883  { 8880728962164096960u, 1516130949512411069u},
884  {10793931984473187891u, 1212904759609928855u},
885  {17270291175157100626u, 1940647615375886168u},
886  { 2748186495899949531u, 1552518092300708935u},
887  { 2198549196719959625u, 1242014473840567148u},
888  {18275073973719576693u, 1987223158144907436u},
889  {10930710364233751031u, 1589778526515925949u},
890  {12433917106128911148u, 1271822821212740759u},
891  { 8826220925580526867u, 2034916513940385215u},
892  { 7060976740464421494u, 1627933211152308172u},
893  {16716827836597268165u, 1302346568921846537u},
894  {11989529279587987770u, 2083754510274954460u},
895  { 9591623423670390216u, 1667003608219963568u},
896  {15051996368420132820u, 1333602886575970854u},
897  {13015147745246481542u, 2133764618521553367u},
898  { 3033420566713364587u, 1707011694817242694u},
899  { 6116085268112601993u, 1365609355853794155u},
900  { 9785736428980163188u, 2184974969366070648u},
901  {15207286772667951197u, 1747979975492856518u},
902  { 1097782973908629988u, 1398383980394285215u},
903  { 1756452758253807981u, 2237414368630856344u},
904  { 5094511021344956708u, 1789931494904685075u},
905  { 4075608817075965366u, 1431945195923748060u},
906  { 6520974107321544586u, 2291112313477996896u},
907  { 1527430471115325346u, 1832889850782397517u},
908  {12289990821117991246u, 1466311880625918013u},
909  {17210690286378213644u, 1173049504500734410u},
910  { 9090360384495590213u, 1876879207201175057u},
911  {18340334751822203140u, 1501503365760940045u},
912  {14672267801457762512u, 1201202692608752036u},
913  {16096930852848599373u, 1921924308174003258u},
914  { 1809498238053148529u, 1537539446539202607u},
915  {12515645034668249793u, 1230031557231362085u},
916  { 1578287981759648052u, 1968050491570179337u},
917  {12330676829633449412u, 1574440393256143469u},
918  {13553890278448669853u, 1259552314604914775u},
919  { 3239480371808320148u, 2015283703367863641u},
920  {17348979556414297411u, 1612226962694290912u},
921  { 6500486015647617283u, 1289781570155432730u},
922  {10400777625036187652u, 2063650512248692368u},
923  {15699319729512770768u, 1650920409798953894u},
924  {16248804598352126938u, 1320736327839163115u},
925  { 7551343283653851484u, 2113178124542660985u},
926  { 6041074626923081187u, 1690542499634128788u},
927  {12211557331022285596u, 1352433999707303030u},
928  { 1091747655926105338u, 2163894399531684849u},
929  { 4562746939482794594u, 1731115519625347879u},
930  { 7339546366328145998u, 1384892415700278303u},
931  { 8053925371383123274u, 2215827865120445285u},
932  { 6443140297106498619u, 1772662292096356228u},
933  {12533209867169019542u, 1418129833677084982u},
934  { 5295740528502789974u, 2269007733883335972u},
935  {15304638867027962949u, 1815206187106668777u},
936  { 4865013464138549713u, 1452164949685335022u},
937  {14960057215536570740u, 1161731959748268017u},
938  { 9178696285890871890u, 1858771135597228828u},
939  {14721654658196518159u, 1487016908477783062u},
940  { 4398626097073393881u, 1189613526782226450u},
941  { 7037801755317430209u, 1903381642851562320u},
942  { 5630241404253944167u, 1522705314281249856u},
943  { 814844308661245011u, 1218164251424999885u},
944  { 1303750893857992017u, 1949062802279999816u},
945  {15800395974054034906u, 1559250241823999852u},
946  { 5261619149759407279u, 1247400193459199882u},
947  {12107939454356961969u, 1995840309534719811u},
948  { 5997002748743659252u, 1596672247627775849u},
949  { 8486951013736837725u, 1277337798102220679u},
950  { 2511075177753209390u, 2043740476963553087u},
951  {13076906586428298482u, 1634992381570842469u},
952  {14150874083884549109u, 1307993905256673975u},
953  { 4194654460505726958u, 2092790248410678361u},
954  {18113118827372222859u, 1674232198728542688u},
955  { 3422448617672047318u, 1339385758982834151u},
956  {16543964232501006678u, 2143017214372534641u},
957  { 9545822571258895019u, 1714413771498027713u},
958  {15015355686490936662u, 1371531017198422170u},
959  { 5577825024675947042u, 2194449627517475473u},
960  {11840957649224578280u, 1755559702013980378u},
961  {16851463748863483271u, 1404447761611184302u},
962  {12204946739213931940u, 2247116418577894884u},
963  {13453306206113055875u, 1797693134862315907u},
964  { 3383947335406624054u, 1438154507889852726u},
965  {16482362180876329456u, 2301047212623764361u},
966  { 9496540929959153242u, 1840837770099011489u},
967  {11286581558709232917u, 1472670216079209191u},
968  { 5339916432225476010u, 1178136172863367353u},
969  { 4854517476818851293u, 1885017876581387765u},
970  { 3883613981455081034u, 1508014301265110212u},
971  {14174937629389795797u, 1206411441012088169u},
972  {11611853762797942306u, 1930258305619341071u},
973  { 5600134195496443521u, 1544206644495472857u},
974  {15548153800622885787u, 1235365315596378285u},
975  { 6430302007287065643u, 1976584504954205257u},
976  {16212288050055383484u, 1581267603963364205u},
977  {12969830440044306787u, 1265014083170691364u},
978  { 9683682259845159889u, 2024022533073106183u},
979  {15125643437359948558u, 1619218026458484946u},
980  { 8411165935146048523u, 1295374421166787957u},
981  {17147214310975587960u, 2072599073866860731u},
982  {10028422634038560045u, 1658079259093488585u},
983  { 8022738107230848036u, 1326463407274790868u},
984  { 9147032156827446534u, 2122341451639665389u},
985  {11006974540203867551u, 1697873161311732311u},
986  { 5116230817421183718u, 1358298529049385849u},
987  {15564666937357714594u, 2173277646479017358u},
988  { 1383687105660440706u, 1738622117183213887u},
989  {12174996128754083534u, 1390897693746571109u},
990  { 8411947361780802685u, 2225436309994513775u},
991  { 6729557889424642148u, 1780349047995611020u},
992  { 5383646311539713719u, 1424279238396488816u},
993  { 1235136468979721303u, 2278846781434382106u},
994  {15745504434151418335u, 1823077425147505684u},
995  {16285752362063044992u, 1458461940118004547u},
996  { 5649904260166615347u, 1166769552094403638u},
997  { 5350498001524674232u, 1866831283351045821u},
998  { 591049586477829062u, 1493465026680836657u},
999  {11540886113407994219u, 1194772021344669325u},
1000  { 18673707743239135u, 1911635234151470921u},
1001  {14772334225162232601u, 1529308187321176736u},
1002  { 8128518565387875758u, 1223446549856941389u},
1003  { 1937583260394870242u, 1957514479771106223u},
1004  { 8928764237799716840u, 1566011583816884978u},
1005  {14521709019723594119u, 1252809267053507982u},
1006  { 8477339172590109297u, 2004494827285612772u},
1007  {17849917782297818407u, 1603595861828490217u},
1008  { 6901236596354434079u, 1282876689462792174u},
1009  {18420676183650915173u, 2052602703140467478u},
1010  { 3668494502695001169u, 1642082162512373983u},
1011  {10313493231639821582u, 1313665730009899186u},
1012  { 9122891541139893884u, 2101865168015838698u},
1013  {14677010862395735754u, 1681492134412670958u},
1014  { 673562245690857633u, 1345193707530136767u}
1015 };
1016 
1017 static const u64 DOUBLE_POW5_SPLIT[DOUBLE_POW5_TABLE_SIZE][2] = {
1018  { 0u, 1152921504606846976u},
1019  { 0u, 1441151880758558720u},
1020  { 0u, 1801439850948198400u},
1021  { 0u, 2251799813685248000u},
1022  { 0u, 1407374883553280000u},
1023  { 0u, 1759218604441600000u},
1024  { 0u, 2199023255552000000u},
1025  { 0u, 1374389534720000000u},
1026  { 0u, 1717986918400000000u},
1027  { 0u, 2147483648000000000u},
1028  { 0u, 1342177280000000000u},
1029  { 0u, 1677721600000000000u},
1030  { 0u, 2097152000000000000u},
1031  { 0u, 1310720000000000000u},
1032  { 0u, 1638400000000000000u},
1033  { 0u, 2048000000000000000u},
1034  { 0u, 1280000000000000000u},
1035  { 0u, 1600000000000000000u},
1036  { 0u, 2000000000000000000u},
1037  { 0u, 1250000000000000000u},
1038  { 0u, 1562500000000000000u},
1039  { 0u, 1953125000000000000u},
1040  { 0u, 1220703125000000000u},
1041  { 0u, 1525878906250000000u},
1042  { 0u, 1907348632812500000u},
1043  { 0u, 1192092895507812500u},
1044  { 0u, 1490116119384765625u},
1045  { 4611686018427387904u, 1862645149230957031u},
1046  { 9799832789158199296u, 1164153218269348144u},
1047  {12249790986447749120u, 1455191522836685180u},
1048  {15312238733059686400u, 1818989403545856475u},
1049  {14528612397897220096u, 2273736754432320594u},
1050  {13692068767113150464u, 1421085471520200371u},
1051  {12503399940464050176u, 1776356839400250464u},
1052  {15629249925580062720u, 2220446049250313080u},
1053  { 9768281203487539200u, 1387778780781445675u},
1054  { 7598665485932036096u, 1734723475976807094u},
1055  { 274959820560269312u, 2168404344971008868u},
1056  { 9395221924704944128u, 1355252715606880542u},
1057  { 2520655369026404352u, 1694065894508600678u},
1058  {12374191248137781248u, 2117582368135750847u},
1059  {14651398557727195136u, 1323488980084844279u},
1060  {13702562178731606016u, 1654361225106055349u},
1061  { 3293144668132343808u, 2067951531382569187u},
1062  {18199116482078572544u, 1292469707114105741u},
1063  { 8913837547316051968u, 1615587133892632177u},
1064  {15753982952572452864u, 2019483917365790221u},
1065  {12152082354571476992u, 1262177448353618888u},
1066  {15190102943214346240u, 1577721810442023610u},
1067  { 9764256642163156992u, 1972152263052529513u},
1068  {17631875447420442880u, 1232595164407830945u},
1069  { 8204786253993389888u, 1540743955509788682u},
1070  { 1032610780636961552u, 1925929944387235853u},
1071  { 2951224747111794922u, 1203706215242022408u},
1072  { 3689030933889743652u, 1504632769052528010u},
1073  {13834660704216955373u, 1880790961315660012u},
1074  {17870034976990372916u, 1175494350822287507u},
1075  {17725857702810578241u, 1469367938527859384u},
1076  { 3710578054803671186u, 1836709923159824231u},
1077  { 26536550077201078u, 2295887403949780289u},
1078  {11545800389866720434u, 1434929627468612680u},
1079  {14432250487333400542u, 1793662034335765850u},
1080  { 8816941072311974870u, 2242077542919707313u},
1081  {17039803216263454053u, 1401298464324817070u},
1082  {12076381983474541759u, 1751623080406021338u},
1083  { 5872105442488401391u, 2189528850507526673u},
1084  {15199280947623720629u, 1368455531567204170u},
1085  { 9775729147674874978u, 1710569414459005213u},
1086  {16831347453020981627u, 2138211768073756516u},
1087  { 1296220121283337709u, 1336382355046097823u},
1088  {15455333206886335848u, 1670477943807622278u},
1089  {10095794471753144002u, 2088097429759527848u},
1090  { 6309871544845715001u, 1305060893599704905u},
1091  {12499025449484531656u, 1631326116999631131u},
1092  {11012095793428276666u, 2039157646249538914u},
1093  {11494245889320060820u, 1274473528905961821u},
1094  { 532749306367912313u, 1593091911132452277u},
1095  { 5277622651387278295u, 1991364888915565346u},
1096  { 7910200175544436838u, 1244603055572228341u},
1097  {14499436237857933952u, 1555753819465285426u},
1098  { 8900923260467641632u, 1944692274331606783u},
1099  {12480606065433357876u, 1215432671457254239u},
1100  {10989071563364309441u, 1519290839321567799u},
1101  { 9124653435777998898u, 1899113549151959749u},
1102  { 8008751406574943263u, 1186945968219974843u},
1103  { 5399253239791291175u, 1483682460274968554u},
1104  {15972438586593889776u, 1854603075343710692u},
1105  { 759402079766405302u, 1159126922089819183u},
1106  {14784310654990170340u, 1448908652612273978u},
1107  { 9257016281882937117u, 1811135815765342473u},
1108  {16182956370781059300u, 2263919769706678091u},
1109  { 7808504722524468110u, 1414949856066673807u},
1110  { 5148944884728197234u, 1768687320083342259u},
1111  { 1824495087482858639u, 2210859150104177824u},
1112  { 1140309429676786649u, 1381786968815111140u},
1113  { 1425386787095983311u, 1727233711018888925u},
1114  { 6393419502297367043u, 2159042138773611156u},
1115  {13219259225790630210u, 1349401336733506972u},
1116  {16524074032238287762u, 1686751670916883715u},
1117  {16043406521870471799u, 2108439588646104644u},
1118  { 803757039314269066u, 1317774742903815403u},
1119  {14839754354425000045u, 1647218428629769253u},
1120  { 4714634887749086344u, 2059023035787211567u},
1121  { 9864175832484260821u, 1286889397367007229u},
1122  {16941905809032713930u, 1608611746708759036u},
1123  { 2730638187581340797u, 2010764683385948796u},
1124  {10930020904093113806u, 1256727927116217997u},
1125  {18274212148543780162u, 1570909908895272496u},
1126  { 4396021111970173586u, 1963637386119090621u},
1127  { 5053356204195052443u, 1227273366324431638u},
1128  {15540067292098591362u, 1534091707905539547u},
1129  {14813398096695851299u, 1917614634881924434u},
1130  {13870059828862294966u, 1198509146801202771u},
1131  {12725888767650480803u, 1498136433501503464u},
1132  {15907360959563101004u, 1872670541876879330u},
1133  {14553786618154326031u, 1170419088673049581u},
1134  { 4357175217410743827u, 1463023860841311977u},
1135  {10058155040190817688u, 1828779826051639971u},
1136  { 7961007781811134206u, 2285974782564549964u},
1137  {14199001900486734687u, 1428734239102843727u},
1138  {13137066357181030455u, 1785917798878554659u},
1139  {11809646928048900164u, 2232397248598193324u},
1140  {16604401366885338411u, 1395248280373870827u},
1141  {16143815690179285109u, 1744060350467338534u},
1142  {10956397575869330579u, 2180075438084173168u},
1143  { 6847748484918331612u, 1362547148802608230u},
1144  {17783057643002690323u, 1703183936003260287u},
1145  {17617136035325974999u, 2128979920004075359u},
1146  {17928239049719816230u, 1330612450002547099u},
1147  {17798612793722382384u, 1663265562503183874u},
1148  {13024893955298202172u, 2079081953128979843u},
1149  { 5834715712847682405u, 1299426220705612402u},
1150  {16516766677914378815u, 1624282775882015502u},
1151  {11422586310538197711u, 2030353469852519378u},
1152  {11750802462513761473u, 1268970918657824611u},
1153  {10076817059714813937u, 1586213648322280764u},
1154  {12596021324643517422u, 1982767060402850955u},
1155  { 5566670318688504437u, 1239229412751781847u},
1156  { 2346651879933242642u, 1549036765939727309u},
1157  { 7545000868343941206u, 1936295957424659136u},
1158  { 4715625542714963254u, 1210184973390411960u},
1159  { 5894531928393704067u, 1512731216738014950u},
1160  {16591536947346905892u, 1890914020922518687u},
1161  {17287239619732898039u, 1181821263076574179u},
1162  {16997363506238734644u, 1477276578845717724u},
1163  { 2799960309088866689u, 1846595723557147156u},
1164  {10973347230035317489u, 1154122327223216972u},
1165  {13716684037544146861u, 1442652909029021215u},
1166  {12534169028502795672u, 1803316136286276519u},
1167  {11056025267201106687u, 2254145170357845649u},
1168  {18439230838069161439u, 1408840731473653530u},
1169  {13825666510731675991u, 1761050914342066913u},
1170  { 3447025083132431277u, 2201313642927583642u},
1171  { 6766076695385157452u, 1375821026829739776u},
1172  { 8457595869231446815u, 1719776283537174720u},
1173  {10571994836539308519u, 2149720354421468400u},
1174  { 6607496772837067824u, 1343575221513417750u},
1175  {17482743002901110588u, 1679469026891772187u},
1176  {17241742735199000331u, 2099336283614715234u},
1177  {15387775227926763111u, 1312085177259197021u},
1178  { 5399660979626290177u, 1640106471573996277u},
1179  {11361262242960250625u, 2050133089467495346u},
1180  {11712474920277544544u, 1281333180917184591u},
1181  {10028907631919542777u, 1601666476146480739u},
1182  { 7924448521472040567u, 2002083095183100924u},
1183  {14176152362774801162u, 1251301934489438077u},
1184  { 3885132398186337741u, 1564127418111797597u},
1185  { 9468101516160310080u, 1955159272639746996u},
1186  {15140935484454969608u, 1221974545399841872u},
1187  { 479425281859160394u, 1527468181749802341u},
1188  { 5210967620751338397u, 1909335227187252926u},
1189  {17091912818251750210u, 1193334516992033078u},
1190  {12141518985959911954u, 1491668146240041348u},
1191  {15176898732449889943u, 1864585182800051685u},
1192  {11791404716994875166u, 1165365739250032303u},
1193  {10127569877816206054u, 1456707174062540379u},
1194  { 8047776328842869663u, 1820883967578175474u},
1195  { 836348374198811271u, 2276104959472719343u},
1196  { 7440246761515338900u, 1422565599670449589u},
1197  {13911994470321561530u, 1778206999588061986u},
1198  { 8166621051047176104u, 2222758749485077483u},
1199  { 2798295147690791113u, 1389224218428173427u},
1200  {17332926989895652603u, 1736530273035216783u},
1201  {17054472718942177850u, 2170662841294020979u},
1202  { 8353202440125167204u, 1356664275808763112u},
1203  {10441503050156459005u, 1695830344760953890u},
1204  { 3828506775840797949u, 2119787930951192363u},
1205  { 86973725686804766u, 1324867456844495227u},
1206  {13943775212390669669u, 1656084321055619033u},
1207  { 3594660960206173375u, 2070105401319523792u},
1208  { 2246663100128858359u, 1293815875824702370u},
1209  {12031700912015848757u, 1617269844780877962u},
1210  { 5816254103165035138u, 2021587305976097453u},
1211  { 5941001823691840913u, 1263492066235060908u},
1212  { 7426252279614801142u, 1579365082793826135u},
1213  { 4671129331091113523u, 1974206353492282669u},
1214  { 5225298841145639904u, 1233878970932676668u},
1215  { 6531623551432049880u, 1542348713665845835u},
1216  { 3552843420862674446u, 1927935892082307294u},
1217  {16055585193321335241u, 1204959932551442058u},
1218  {10846109454796893243u, 1506199915689302573u},
1219  {18169322836923504458u, 1882749894611628216u},
1220  {11355826773077190286u, 1176718684132267635u},
1221  { 9583097447919099954u, 1470898355165334544u},
1222  {11978871809898874942u, 1838622943956668180u},
1223  {14973589762373593678u, 2298278679945835225u},
1224  { 2440964573842414192u, 1436424174966147016u},
1225  { 3051205717303017741u, 1795530218707683770u},
1226  {13037379183483547984u, 2244412773384604712u},
1227  { 8148361989677217490u, 1402757983365377945u},
1228  {14797138505523909766u, 1753447479206722431u},
1229  {13884737113477499304u, 2191809349008403039u},
1230  {15595489723564518921u, 1369880843130251899u},
1231  {14882676136028260747u, 1712351053912814874u},
1232  { 9379973133180550126u, 2140438817391018593u},
1233  {17391698254306313589u, 1337774260869386620u},
1234  { 3292878744173340370u, 1672217826086733276u},
1235  { 4116098430216675462u, 2090272282608416595u},
1236  { 266718509671728212u, 1306420176630260372u},
1237  { 333398137089660265u, 1633025220787825465u},
1238  { 5028433689789463235u, 2041281525984781831u},
1239  {10060300083759496378u, 1275800953740488644u},
1240  {12575375104699370472u, 1594751192175610805u},
1241  { 1884160825592049379u, 1993438990219513507u},
1242  {17318501580490888525u, 1245899368887195941u},
1243  { 7813068920331446945u, 1557374211108994927u},
1244  { 5154650131986920777u, 1946717763886243659u},
1245  { 915813323278131534u, 1216698602428902287u},
1246  {14979824709379828129u, 1520873253036127858u},
1247  { 9501408849870009354u, 1901091566295159823u},
1248  {12855909558809837702u, 1188182228934474889u},
1249  { 2234828893230133415u, 1485227786168093612u},
1250  { 2793536116537666769u, 1856534732710117015u},
1251  { 8663489100477123587u, 1160334207943823134u},
1252  { 1605989338741628675u, 1450417759929778918u},
1253  {11230858710281811652u, 1813022199912223647u},
1254  { 9426887369424876662u, 2266277749890279559u},
1255  {12809333633531629769u, 1416423593681424724u},
1256  {16011667041914537212u, 1770529492101780905u},
1257  { 6179525747111007803u, 2213161865127226132u},
1258  {13085575628799155685u, 1383226165704516332u},
1259  {16356969535998944606u, 1729032707130645415u},
1260  {15834525901571292854u, 2161290883913306769u},
1261  { 2979049660840976177u, 1350806802445816731u},
1262  {17558870131333383934u, 1688508503057270913u},
1263  { 8113529608884566205u, 2110635628821588642u},
1264  { 9682642023980241782u, 1319147268013492901u},
1265  {16714988548402690132u, 1648934085016866126u},
1266  {11670363648648586857u, 2061167606271082658u},
1267  {11905663298832754689u, 1288229753919426661u},
1268  { 1047021068258779650u, 1610287192399283327u},
1269  {15143834390605638274u, 2012858990499104158u},
1270  { 4853210475701136017u, 1258036869061940099u},
1271  { 1454827076199032118u, 1572546086327425124u},
1272  { 1818533845248790147u, 1965682607909281405u},
1273  { 3442426662494187794u, 1228551629943300878u},
1274  {13526405364972510550u, 1535689537429126097u},
1275  { 3072948650933474476u, 1919611921786407622u},
1276  {15755650962115585259u, 1199757451116504763u},
1277  {15082877684217093670u, 1499696813895630954u},
1278  { 9630225068416591280u, 1874621017369538693u},
1279  { 8324733676974063502u, 1171638135855961683u},
1280  { 5794231077790191473u, 1464547669819952104u},
1281  { 7242788847237739342u, 1830684587274940130u},
1282  {18276858095901949986u, 2288355734093675162u},
1283  {16034722328366106645u, 1430222333808546976u},
1284  { 1596658836748081690u, 1787777917260683721u},
1285  { 6607509564362490017u, 2234722396575854651u},
1286  { 1823850468512862308u, 1396701497859909157u},
1287  { 6891499104068465790u, 1745876872324886446u},
1288  {17837745916940358045u, 2182346090406108057u},
1289  { 4231062170446641922u, 1363966306503817536u},
1290  { 5288827713058302403u, 1704957883129771920u},
1291  { 6611034641322878003u, 2131197353912214900u},
1292  {13355268687681574560u, 1331998346195134312u},
1293  {16694085859601968200u, 1664997932743917890u},
1294  {11644235287647684442u, 2081247415929897363u},
1295  { 4971804045566108824u, 1300779634956185852u},
1296  { 6214755056957636030u, 1625974543695232315u},
1297  { 3156757802769657134u, 2032468179619040394u},
1298  { 6584659645158423613u, 1270292612261900246u},
1299  {17454196593302805324u, 1587865765327375307u},
1300  {17206059723201118751u, 1984832206659219134u},
1301  { 6142101308573311315u, 1240520129162011959u},
1302  { 3065940617289251240u, 1550650161452514949u},
1303  { 8444111790038951954u, 1938312701815643686u},
1304  { 665883850346957067u, 1211445438634777304u},
1305  { 832354812933696334u, 1514306798293471630u},
1306  {10263815553021896226u, 1892883497866839537u},
1307  {17944099766707154901u, 1183052186166774710u},
1308  {13206752671529167818u, 1478815232708468388u},
1309  {16508440839411459773u, 1848519040885585485u},
1310  {12623618533845856310u, 1155324400553490928u},
1311  {15779523167307320387u, 1444155500691863660u},
1312  { 1277659885424598868u, 1805194375864829576u},
1313  { 1597074856780748586u, 2256492969831036970u},
1314  { 5609857803915355770u, 1410308106144398106u},
1315  {16235694291748970521u, 1762885132680497632u},
1316  { 1847873790976661535u, 2203606415850622041u},
1317  {12684136165428883219u, 1377254009906638775u},
1318  {11243484188358716120u, 1721567512383298469u},
1319  { 219297180166231438u, 2151959390479123087u},
1320  { 7054589765244976505u, 1344974619049451929u},
1321  {13429923224983608535u, 1681218273811814911u},
1322  {12175718012802122765u, 2101522842264768639u},
1323  {14527352785642408584u, 1313451776415480399u},
1324  {13547504963625622826u, 1641814720519350499u},
1325  {12322695186104640628u, 2052268400649188124u},
1326  {16925056528170176201u, 1282667750405742577u},
1327  { 7321262604930556539u, 1603334688007178222u},
1328  {18374950293017971482u, 2004168360008972777u},
1329  { 4566814905495150320u, 1252605225005607986u},
1330  {14931890668723713708u, 1565756531257009982u},
1331  { 9441491299049866327u, 1957195664071262478u},
1332  { 1289246043478778550u, 1223247290044539049u},
1333  { 6223243572775861092u, 1529059112555673811u},
1334  { 3167368447542438461u, 1911323890694592264u},
1335  { 1979605279714024038u, 1194577431684120165u},
1336  { 7086192618069917952u, 1493221789605150206u},
1337  {18081112809442173248u, 1866527237006437757u},
1338  {13606538515115052232u, 1166579523129023598u},
1339  { 7784801107039039482u, 1458224403911279498u},
1340  { 507629346944023544u, 1822780504889099373u},
1341  { 5246222702107417334u, 2278475631111374216u},
1342  { 3278889188817135834u, 1424047269444608885u},
1343  { 8710297504448807696u, 1780059086805761106u}
1344 };
string string_from_raw_n(const char *raw, usize n)
Construct a string from n chars of raw character data.
Definition: string.c:27
string_view string_view_from_string(const string str)
Create a new string view of a whole string.
Definition: string.c:126
#define KB_UBIT(n)
Get unsigned value with the n-th bit set to 1. All other bits are 0.
Definition: defines.h:72
#define KB_MAX(x, y)
Ternary to get the maximum of two numbers.
Definition: defines.h:43
#define UNUSED(x)
Mark parameter as unused.
Definition: defines.h:21
#define KB_ASSERT(expr,...)
Perform runtime assertion and log failures.
Definition: log.h:133