summaryrefslogtreecommitdiff
path: root/examples/redis-unstable/deps/fpconv
diff options
context:
space:
mode:
Diffstat (limited to 'examples/redis-unstable/deps/fpconv')
-rw-r--r--examples/redis-unstable/deps/fpconv/LICENSE.txt23
-rw-r--r--examples/redis-unstable/deps/fpconv/Makefile27
-rw-r--r--examples/redis-unstable/deps/fpconv/README.md9
-rw-r--r--examples/redis-unstable/deps/fpconv/fpconv_dtoa.c373
-rw-r--r--examples/redis-unstable/deps/fpconv/fpconv_dtoa.h45
-rw-r--r--examples/redis-unstable/deps/fpconv/fpconv_powers.h133
6 files changed, 610 insertions, 0 deletions
diff --git a/examples/redis-unstable/deps/fpconv/LICENSE.txt b/examples/redis-unstable/deps/fpconv/LICENSE.txt
new file mode 100644
index 0000000..36b7cd9
--- /dev/null
+++ b/examples/redis-unstable/deps/fpconv/LICENSE.txt
@@ -0,0 +1,23 @@
1Boost Software License - Version 1.0 - August 17th, 2003
2
3Permission is hereby granted, free of charge, to any person or organization
4obtaining a copy of the software and accompanying documentation covered by
5this license (the "Software") to use, reproduce, display, distribute,
6execute, and transmit the Software, and to prepare derivative works of the
7Software, and to permit third-parties to whom the Software is furnished to
8do so, all subject to the following:
9
10The copyright notices in the Software and this entire statement, including
11the above license grant, this restriction and the following disclaimer,
12must be included in all copies of the Software, in whole or in part, and
13all derivative works of the Software, unless such copies or derivative
14works are solely in the form of machine-executable object code generated by
15a source language processor.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
20SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
21FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
22ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23DEALINGS IN THE SOFTWARE.
diff --git a/examples/redis-unstable/deps/fpconv/Makefile b/examples/redis-unstable/deps/fpconv/Makefile
new file mode 100644
index 0000000..2654888
--- /dev/null
+++ b/examples/redis-unstable/deps/fpconv/Makefile
@@ -0,0 +1,27 @@
1STD=
2WARN= -Wall
3OPT= -Os
4
5R_CFLAGS= $(STD) $(WARN) $(OPT) $(DEBUG) $(CFLAGS)
6R_LDFLAGS= $(LDFLAGS)
7DEBUG= -g
8
9R_CC=$(CC) $(R_CFLAGS)
10R_LD=$(CC) $(R_LDFLAGS)
11
12AR= ar
13ARFLAGS= rcs
14
15libfpconv.a: fpconv_dtoa.o
16 $(AR) $(ARFLAGS) $@ $+
17
18fpconv_dtoa.o: fpconv_dtoa.h fpconv_dtoa.c
19
20.c.o:
21 $(R_CC) -c $<
22
23clean:
24 rm -f *.o
25 rm -f *.a
26
27
diff --git a/examples/redis-unstable/deps/fpconv/README.md b/examples/redis-unstable/deps/fpconv/README.md
new file mode 100644
index 0000000..d64ca68
--- /dev/null
+++ b/examples/redis-unstable/deps/fpconv/README.md
@@ -0,0 +1,9 @@
1libfpconv
2
3----------------------------------------------
4
5Fast and accurate double to string conversion based on Florian Loitsch's Grisu-algorithm[1].
6
7This port contains a subset of the 'C' version of Fast and accurate double to string conversion based on Florian Loitsch's Grisu-algorithm available at [github.com/night-shift/fpconv](https://github.com/night-shift/fpconv)).
8
9[1] https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
diff --git a/examples/redis-unstable/deps/fpconv/fpconv_dtoa.c b/examples/redis-unstable/deps/fpconv/fpconv_dtoa.c
new file mode 100644
index 0000000..ad2f2de
--- /dev/null
+++ b/examples/redis-unstable/deps/fpconv/fpconv_dtoa.c
@@ -0,0 +1,373 @@
1/* fpconv_dtoa.c -- floating point conversion utilities.
2 *
3 * Fast and accurate double to string conversion based on Florian Loitsch's
4 * Grisu-algorithm[1].
5 *
6 * [1] https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
7 * ----------------------------------------------------------------------------
8 *
9 * Copyright (c) 2013-2019, night-shift <as.smljk at gmail dot com>
10 * Copyright (c) 2009, Florian Loitsch < florian.loitsch at inria dot fr >
11 * All rights reserved.
12 *
13 * Boost Software License - Version 1.0 - August 17th, 2003
14 *
15 * Permission is hereby granted, free of charge, to any person or organization
16 * obtaining a copy of the software and accompanying documentation covered by
17 * this license (the "Software") to use, reproduce, display, distribute,
18 * execute, and transmit the Software, and to prepare derivative works of the
19 * Software, and to permit third-parties to whom the Software is furnished to
20 * do so, all subject to the following:
21 *
22 * The copyright notices in the Software and this entire statement, including
23 * the above license grant, this restriction and the following disclaimer,
24 * must be included in all copies of the Software, in whole or in part, and
25 * all derivative works of the Software, unless such copies or derivative
26 * works are solely in the form of machine-executable object code generated by
27 * a source language processor.
28 *
29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
32 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
33 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
34 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
35 * DEALINGS IN THE SOFTWARE.
36 */
37
38#include "fpconv_dtoa.h"
39
40#include "fpconv_powers.h"
41
42#include <stdbool.h>
43#include <string.h>
44
45#define fracmask 0x000FFFFFFFFFFFFFU
46#define expmask 0x7FF0000000000000U
47#define hiddenbit 0x0010000000000000U
48#define signmask 0x8000000000000000U
49#define expbias (1023 + 52)
50
51#define absv(n) ((n) < 0 ? -(n) : (n))
52#define minv(a, b) ((a) < (b) ? (a) : (b))
53
54static uint64_t tens[] = { 10000000000000000000U,
55 1000000000000000000U,
56 100000000000000000U,
57 10000000000000000U,
58 1000000000000000U,
59 100000000000000U,
60 10000000000000U,
61 1000000000000U,
62 100000000000U,
63 10000000000U,
64 1000000000U,
65 100000000U,
66 10000000U,
67 1000000U,
68 100000U,
69 10000U,
70 1000U,
71 100U,
72 10U,
73 1U };
74
75static inline uint64_t get_dbits(double d) {
76 union
77 {
78 double dbl;
79 uint64_t i;
80 } dbl_bits = { d };
81
82 return dbl_bits.i;
83}
84
85static Fp build_fp(double d) {
86 uint64_t bits = get_dbits(d);
87
88 Fp fp;
89 fp.frac = bits & fracmask;
90 fp.exp = (bits & expmask) >> 52;
91
92 if (fp.exp) {
93 fp.frac += hiddenbit;
94 fp.exp -= expbias;
95
96 } else {
97 fp.exp = -expbias + 1;
98 }
99
100 return fp;
101}
102
103static void normalize(Fp *fp) {
104 while ((fp->frac & hiddenbit) == 0) {
105 fp->frac <<= 1;
106 fp->exp--;
107 }
108
109 int shift = 64 - 52 - 1;
110 fp->frac <<= shift;
111 fp->exp -= shift;
112}
113
114static void get_normalized_boundaries(Fp *fp, Fp *lower, Fp *upper) {
115 upper->frac = (fp->frac << 1) + 1;
116 upper->exp = fp->exp - 1;
117
118 while ((upper->frac & (hiddenbit << 1)) == 0) {
119 upper->frac <<= 1;
120 upper->exp--;
121 }
122
123 int u_shift = 64 - 52 - 2;
124
125 upper->frac <<= u_shift;
126 upper->exp = upper->exp - u_shift;
127
128 int l_shift = fp->frac == hiddenbit ? 2 : 1;
129
130 lower->frac = (fp->frac << l_shift) - 1;
131 lower->exp = fp->exp - l_shift;
132
133 lower->frac <<= lower->exp - upper->exp;
134 lower->exp = upper->exp;
135}
136
137static Fp multiply(Fp *a, Fp *b) {
138 const uint64_t lomask = 0x00000000FFFFFFFF;
139
140 uint64_t ah_bl = (a->frac >> 32) * (b->frac & lomask);
141 uint64_t al_bh = (a->frac & lomask) * (b->frac >> 32);
142 uint64_t al_bl = (a->frac & lomask) * (b->frac & lomask);
143 uint64_t ah_bh = (a->frac >> 32) * (b->frac >> 32);
144
145 uint64_t tmp = (ah_bl & lomask) + (al_bh & lomask) + (al_bl >> 32);
146 /* round up */
147 tmp += 1U << 31;
148
149 Fp fp = { ah_bh + (ah_bl >> 32) + (al_bh >> 32) + (tmp >> 32), a->exp + b->exp + 64 };
150
151 return fp;
152}
153
154static void round_digit(char *digits,
155 int ndigits,
156 uint64_t delta,
157 uint64_t rem,
158 uint64_t kappa,
159 uint64_t frac) {
160 while (rem < frac && delta - rem >= kappa &&
161 (rem + kappa < frac || frac - rem > rem + kappa - frac)) {
162 digits[ndigits - 1]--;
163 rem += kappa;
164 }
165}
166
167static int generate_digits(Fp *fp, Fp *upper, Fp *lower, char *digits, int *K) {
168 uint64_t wfrac = upper->frac - fp->frac;
169 uint64_t delta = upper->frac - lower->frac;
170
171 Fp one;
172 one.frac = 1ULL << -upper->exp;
173 one.exp = upper->exp;
174
175 uint64_t part1 = upper->frac >> -one.exp;
176 uint64_t part2 = upper->frac & (one.frac - 1);
177
178 int idx = 0, kappa = 10;
179 uint64_t *divp;
180 /* 1000000000 */
181 for (divp = tens + 10; kappa > 0; divp++) {
182 uint64_t div = *divp;
183 unsigned digit = part1 / div;
184
185 if (digit || idx) {
186 digits[idx++] = digit + '0';
187 }
188
189 part1 -= digit * div;
190 kappa--;
191
192 uint64_t tmp = (part1 << -one.exp) + part2;
193 if (tmp <= delta) {
194 *K += kappa;
195 round_digit(digits, idx, delta, tmp, div << -one.exp, wfrac);
196
197 return idx;
198 }
199 }
200
201 /* 10 */
202 uint64_t *unit = tens + 18;
203
204 while (true) {
205 part2 *= 10;
206 delta *= 10;
207 kappa--;
208
209 unsigned digit = part2 >> -one.exp;
210 if (digit || idx) {
211 digits[idx++] = digit + '0';
212 }
213
214 part2 &= one.frac - 1;
215 if (part2 < delta) {
216 *K += kappa;
217 round_digit(digits, idx, delta, part2, one.frac, wfrac * *unit);
218
219 return idx;
220 }
221
222 unit--;
223 }
224}
225
226static int grisu2(double d, char *digits, int *K) {
227 Fp w = build_fp(d);
228
229 Fp lower, upper;
230 get_normalized_boundaries(&w, &lower, &upper);
231
232 normalize(&w);
233
234 int k;
235 Fp cp = find_cachedpow10(upper.exp, &k);
236
237 w = multiply(&w, &cp);
238 upper = multiply(&upper, &cp);
239 lower = multiply(&lower, &cp);
240
241 lower.frac++;
242 upper.frac--;
243
244 *K = -k;
245
246 return generate_digits(&w, &upper, &lower, digits, K);
247}
248
249static int emit_digits(char *digits, int ndigits, char *dest, int K, bool neg) {
250 int exp = absv(K + ndigits - 1);
251
252 /* write plain integer */
253 if (K >= 0 && (exp < (ndigits + 7))) {
254 memcpy(dest, digits, ndigits);
255 memset(dest + ndigits, '0', K);
256
257 return ndigits + K;
258 }
259
260 /* write decimal w/o scientific notation */
261 if (K < 0 && (K > -7 || exp < 4)) {
262 int offset = ndigits - absv(K);
263 /* fp < 1.0 -> write leading zero */
264 if (offset <= 0) {
265 offset = -offset;
266 dest[0] = '0';
267 dest[1] = '.';
268 memset(dest + 2, '0', offset);
269 memcpy(dest + offset + 2, digits, ndigits);
270
271 return ndigits + 2 + offset;
272
273 /* fp > 1.0 */
274 } else {
275 memcpy(dest, digits, offset);
276 dest[offset] = '.';
277 memcpy(dest + offset + 1, digits + offset, ndigits - offset);
278
279 return ndigits + 1;
280 }
281 }
282
283 /* write decimal w/ scientific notation */
284 ndigits = minv(ndigits, 18 - neg);
285
286 int idx = 0;
287 dest[idx++] = digits[0];
288
289 if (ndigits > 1) {
290 dest[idx++] = '.';
291 memcpy(dest + idx, digits + 1, ndigits - 1);
292 idx += ndigits - 1;
293 }
294
295 dest[idx++] = 'e';
296
297 char sign = K + ndigits - 1 < 0 ? '-' : '+';
298 dest[idx++] = sign;
299
300 int cent = 0;
301
302 if (exp > 99) {
303 cent = exp / 100;
304 dest[idx++] = cent + '0';
305 exp -= cent * 100;
306 }
307 if (exp > 9) {
308 int dec = exp / 10;
309 dest[idx++] = dec + '0';
310 exp -= dec * 10;
311
312 } else if (cent) {
313 dest[idx++] = '0';
314 }
315
316 dest[idx++] = exp % 10 + '0';
317
318 return idx;
319}
320
321static int filter_special(double fp, char *dest) {
322 if (fp == 0.0) {
323 dest[0] = '0';
324 return 1;
325 }
326
327 uint64_t bits = get_dbits(fp);
328
329 bool nan = (bits & expmask) == expmask;
330
331 if (!nan) {
332 return 0;
333 }
334
335 if (bits & fracmask) {
336 dest[0] = 'n';
337 dest[1] = 'a';
338 dest[2] = 'n';
339
340 } else {
341 dest[0] = 'i';
342 dest[1] = 'n';
343 dest[2] = 'f';
344 }
345
346 return 3;
347}
348
349int fpconv_dtoa(double d, char dest[24]) {
350 char digits[18];
351
352 int str_len = 0;
353 bool neg = false;
354
355 if (get_dbits(d) & signmask) {
356 dest[0] = '-';
357 str_len++;
358 neg = true;
359 }
360
361 int spec = filter_special(d, dest + str_len);
362
363 if (spec) {
364 return str_len + spec;
365 }
366
367 int K = 0;
368 int ndigits = grisu2(d, digits, &K);
369
370 str_len += emit_digits(digits, ndigits, dest + str_len, K, neg);
371
372 return str_len;
373}
diff --git a/examples/redis-unstable/deps/fpconv/fpconv_dtoa.h b/examples/redis-unstable/deps/fpconv/fpconv_dtoa.h
new file mode 100644
index 0000000..328ed83
--- /dev/null
+++ b/examples/redis-unstable/deps/fpconv/fpconv_dtoa.h
@@ -0,0 +1,45 @@
1/* fpconv_dtoa.h -- floating point conversion utilities.
2 *
3 * Fast and accurate double to string conversion based on Florian Loitsch's
4 * Grisu-algorithm[1].
5 *
6 * [1] https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
7 * ----------------------------------------------------------------------------
8 *
9 * Copyright (c) 2013-2019, night-shift <as.smljk at gmail dot com>
10 * Copyright (c) 2009, Florian Loitsch < florian.loitsch at inria dot fr >
11 * All rights reserved.
12 *
13 * Boost Software License - Version 1.0 - August 17th, 2003
14 *
15 * Permission is hereby granted, free of charge, to any person or organization
16 * obtaining a copy of the software and accompanying documentation covered by
17 * this license (the "Software") to use, reproduce, display, distribute,
18 * execute, and transmit the Software, and to prepare derivative works of the
19 * Software, and to permit third-parties to whom the Software is furnished to
20 * do so, all subject to the following:
21 *
22 * The copyright notices in the Software and this entire statement, including
23 * the above license grant, this restriction and the following disclaimer,
24 * must be included in all copies of the Software, in whole or in part, and
25 * all derivative works of the Software, unless such copies or derivative
26 * works are solely in the form of machine-executable object code generated by
27 * a source language processor.
28 *
29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
32 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
33 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
34 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
35 * DEALINGS IN THE SOFTWARE.
36 */
37
38#ifndef FPCONV_DTOA_H
39#define FPCONV_DTOA_H
40
41int fpconv_dtoa(double fp, char dest[24]);
42
43#endif
44
45/* [1] http://florian.loitsch.com/publications/dtoa-pldi2010.pdf */
diff --git a/examples/redis-unstable/deps/fpconv/fpconv_powers.h b/examples/redis-unstable/deps/fpconv/fpconv_powers.h
new file mode 100644
index 0000000..bc488f6
--- /dev/null
+++ b/examples/redis-unstable/deps/fpconv/fpconv_powers.h
@@ -0,0 +1,133 @@
1/* fpconv_powers.h -- floating point conversion utilities.
2 *
3 * Fast and accurate double to string conversion based on Florian Loitsch's
4 * Grisu-algorithm[1].
5 *
6 * [1] https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf
7 * ----------------------------------------------------------------------------
8 *
9 * Copyright (c) 2021, Redis Labs
10 * Copyright (c) 2013-2019, night-shift <as.smljk at gmail dot com>
11 * Copyright (c) 2009, Florian Loitsch < florian.loitsch at inria dot fr >
12 * All rights reserved.
13 *
14 * Boost Software License - Version 1.0 - August 17th, 2003
15 *
16 * Permission is hereby granted, free of charge, to any person or organization
17 * obtaining a copy of the software and accompanying documentation covered by
18 * this license (the "Software") to use, reproduce, display, distribute,
19 * execute, and transmit the Software, and to prepare derivative works of the
20 * Software, and to permit third-parties to whom the Software is furnished to
21 * do so, all subject to the following:
22 *
23 * The copyright notices in the Software and this entire statement, including
24 * the above license grant, this restriction and the following disclaimer,
25 * must be included in all copies of the Software, in whole or in part, and
26 * all derivative works of the Software, unless such copies or derivative
27 * works are solely in the form of machine-executable object code generated by
28 * a source language processor.
29 *
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
33 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
34 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
35 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
36 * DEALINGS IN THE SOFTWARE.
37 */
38
39#include <stdint.h>
40
41#define npowers 87
42#define steppowers 8
43#define firstpower -348 /* 10 ^ -348 */
44
45#define expmax -32
46#define expmin -60
47
48
49typedef struct Fp {
50 uint64_t frac;
51 int exp;
52} Fp;
53
54static Fp powers_ten[] = {
55 { 18054884314459144840U, -1220 }, { 13451937075301367670U, -1193 },
56 { 10022474136428063862U, -1166 }, { 14934650266808366570U, -1140 },
57 { 11127181549972568877U, -1113 }, { 16580792590934885855U, -1087 },
58 { 12353653155963782858U, -1060 }, { 18408377700990114895U, -1034 },
59 { 13715310171984221708U, -1007 }, { 10218702384817765436U, -980 },
60 { 15227053142812498563U, -954 }, { 11345038669416679861U, -927 },
61 { 16905424996341287883U, -901 }, { 12595523146049147757U, -874 },
62 { 9384396036005875287U, -847 }, { 13983839803942852151U, -821 },
63 { 10418772551374772303U, -794 }, { 15525180923007089351U, -768 },
64 { 11567161174868858868U, -741 }, { 17236413322193710309U, -715 },
65 { 12842128665889583758U, -688 }, { 9568131466127621947U, -661 },
66 { 14257626930069360058U, -635 }, { 10622759856335341974U, -608 },
67 { 15829145694278690180U, -582 }, { 11793632577567316726U, -555 },
68 { 17573882009934360870U, -529 }, { 13093562431584567480U, -502 },
69 { 9755464219737475723U, -475 }, { 14536774485912137811U, -449 },
70 { 10830740992659433045U, -422 }, { 16139061738043178685U, -396 },
71 { 12024538023802026127U, -369 }, { 17917957937422433684U, -343 },
72 { 13349918974505688015U, -316 }, { 9946464728195732843U, -289 },
73 { 14821387422376473014U, -263 }, { 11042794154864902060U, -236 },
74 { 16455045573212060422U, -210 }, { 12259964326927110867U, -183 },
75 { 18268770466636286478U, -157 }, { 13611294676837538539U, -130 },
76 { 10141204801825835212U, -103 }, { 15111572745182864684U, -77 },
77 { 11258999068426240000U, -50 }, { 16777216000000000000U, -24 },
78 { 12500000000000000000U, 3 }, { 9313225746154785156U, 30 },
79 { 13877787807814456755U, 56 }, { 10339757656912845936U, 83 },
80 { 15407439555097886824U, 109 }, { 11479437019748901445U, 136 },
81 { 17105694144590052135U, 162 }, { 12744735289059618216U, 189 },
82 { 9495567745759798747U, 216 }, { 14149498560666738074U, 242 },
83 { 10542197943230523224U, 269 }, { 15709099088952724970U, 295 },
84 { 11704190886730495818U, 322 }, { 17440603504673385349U, 348 },
85 { 12994262207056124023U, 375 }, { 9681479787123295682U, 402 },
86 { 14426529090290212157U, 428 }, { 10748601772107342003U, 455 },
87 { 16016664761464807395U, 481 }, { 11933345169920330789U, 508 },
88 { 17782069995880619868U, 534 }, { 13248674568444952270U, 561 },
89 { 9871031767461413346U, 588 }, { 14708983551653345445U, 614 },
90 { 10959046745042015199U, 641 }, { 16330252207878254650U, 667 },
91 { 12166986024289022870U, 694 }, { 18130221999122236476U, 720 },
92 { 13508068024458167312U, 747 }, { 10064294952495520794U, 774 },
93 { 14996968138956309548U, 800 }, { 11173611982879273257U, 827 },
94 { 16649979327439178909U, 853 }, { 12405201291620119593U, 880 },
95 { 9242595204427927429U, 907 }, { 13772540099066387757U, 933 },
96 { 10261342003245940623U, 960 }, { 15290591125556738113U, 986 },
97 { 11392378155556871081U, 1013 }, { 16975966327722178521U, 1039 },
98 { 12648080533535911531U, 1066 }
99};
100
101/**
102 * Grisu needs a cache of precomputed powers-of-ten.
103 * This function, given an exponent and an integer k
104 * return the normalized floating-point approximation of the power of 10.
105 * @param exp
106 * @param k
107 * @return
108 */
109static Fp find_cachedpow10(int exp, int* k)
110{
111 const double one_log_ten = 0.30102999566398114;
112
113 const int approx = -(exp + npowers) * one_log_ten;
114 int idx = (approx - firstpower) / steppowers;
115
116 while(1) {
117 int current = exp + powers_ten[idx].exp + 64;
118
119 if(current < expmin) {
120 idx++;
121 continue;
122 }
123
124 if(current > expmax) {
125 idx--;
126 continue;
127 }
128
129 *k = (firstpower + idx * steppowers);
130
131 return powers_ten[idx];
132 }
133}