fast_float_lemire 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 07cb1816f80a71b3bb90315248f7cd7b76473c4581ec7afe706288d03a8b799c
4
+ data.tar.gz: c9edda489ef613ca3203875752499c3dd8b661453faaa54324ae96473b870bca
5
+ SHA512:
6
+ metadata.gz: 4e6d5ad5dd13c5f8b6a915db78db6b9e8f34ad4f6d0a70818d53ffddaee9db77b0585acff7dda0e512f89b3b8e337d67cca1dfaea885330059cf2a75d238b259
7
+ data.tar.gz: 2db311a648507f1aa7f2fb74f1508e3f2d4c419328181085dce0b55e42f41a3db7537887e5e7175570856ab2dc456434f769622b71a03985f7f7b84991156b10
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Maciej Mensfeld
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # FastFloatLemire
2
+
3
+ [![Build Status](https://github.com/mensfeld/fast_float_lemire/actions/workflows/ci.yml/badge.svg)](https://github.com/mensfeld/fast_float_lemire/actions/workflows/ci.yml)
4
+ [![Gem Version](https://badge.fury.io/rb/fast_float_lemire.svg)](https://rubygems.org/gems/fast_float_lemire)
5
+
6
+ Eisel-Lemire algorithm for string-to-float conversion in Ruby.
7
+
8
+ ## About
9
+
10
+ This is an **educational gem** demonstrating why the Eisel-Lemire algorithm was NOT submitted to Ruby core.
11
+
12
+ | Number Type | vs String#to_f |
13
+ |-------------|----------------|
14
+ | Simple (`"1.5"`, `"99.99"`) | **~9% slower** |
15
+ | Complex (`"3.141592653589793"`) | **~2.6x faster** |
16
+
17
+ Most Ruby apps deal with simple numbers, making this a net negative for typical usage.
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ gem install fast_float_lemire
23
+ ```
24
+
25
+ Or add to your Gemfile:
26
+
27
+ ```ruby
28
+ gem 'fast_float_lemire'
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ ```ruby
34
+ require 'fast_float_lemire'
35
+
36
+ FastFloatLemire.parse("3.141592653589793") #=> 3.141592653589793
37
+ FastFloatLemire.parse("1.5") #=> 1.5
38
+ FastFloatLemire.parse("1e10") #=> 10000000000.0
39
+
40
+ # Bulk parsing
41
+ FastFloatLemire.parse_array(["1.0", "2.0", "3.14"]) #=> [1.0, 2.0, 3.14]
42
+ ```
43
+
44
+ ## Benchmarks
45
+
46
+ Run benchmarks with:
47
+
48
+ ```bash
49
+ bundle exec ruby benchmarks/comparison.rb
50
+ ```
51
+
52
+ ## References
53
+
54
+ - [Eisel-Lemire paper](https://arxiv.org/abs/2101.11408) - "Number Parsing at a Gigabyte per Second"
55
+ - [fast_float C++ library](https://github.com/fastfloat/fast_float)
56
+ - [Go implementation](https://github.com/golang/go/blob/master/src/strconv/eisel_lemire.go)
57
+
58
+ ## License
59
+
60
+ MIT
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mkmf'
4
+
5
+ # Check for 128-bit integer support (for optimal performance)
6
+ have_type('__uint128_t')
7
+
8
+ create_makefile('fast_float_lemire/fast_float_lemire')
@@ -0,0 +1,1110 @@
1
+ /*
2
+ * Eisel-Lemire algorithm for fast string-to-double conversion
3
+ *
4
+ * Based on the algorithm by Daniel Lemire and Michael Eisel
5
+ * Reference: "Number Parsing at a Gigabyte per Second" (Software: Practice and Experience, 2021)
6
+ * https://arxiv.org/abs/2101.11408
7
+ *
8
+ * This implementation is based on:
9
+ * - Go standard library (strconv/eisel_lemire.go)
10
+ * - fast_float C++ library (https://github.com/fastfloat/fast_float)
11
+ *
12
+ * Educational Note:
13
+ * This algorithm is ~2.6x faster than strtod for numbers with many significant
14
+ * digits (like Pi with 16 digits), but ~9% SLOWER for simple numbers like "1.5".
15
+ * Since most Ruby applications deal with simple numbers, this optimization was
16
+ * NOT submitted to Ruby core.
17
+ */
18
+
19
+ #include <ruby.h>
20
+ #include <stdint.h>
21
+ #include <stdbool.h>
22
+ #include <string.h>
23
+ #include <stdlib.h>
24
+ #include <math.h>
25
+
26
+ /* ============================================================================
27
+ * Constants
28
+ * ============================================================================ */
29
+
30
+ #define FASTFLOAT_SMALLEST_POWER -342
31
+ #define FASTFLOAT_LARGEST_POWER 308
32
+
33
+ #define DOUBLE_MANTISSA_BITS 52
34
+ #define DOUBLE_EXPONENT_BIAS 1023
35
+
36
+ /* ============================================================================
37
+ * 128-bit multiplication helpers
38
+ * ============================================================================ */
39
+
40
+ #if defined(__SIZEOF_INT128__) && !defined(FAST_FLOAT_NO_INT128)
41
+ typedef __uint128_t ff_uint128_t;
42
+
43
+ static inline uint64_t
44
+ mul128_upper64(uint64_t a, uint64_t b)
45
+ {
46
+ ff_uint128_t product = (ff_uint128_t)a * (ff_uint128_t)b;
47
+ return (uint64_t)(product >> 64);
48
+ }
49
+
50
+ static inline void
51
+ mul128(uint64_t a, uint64_t b, uint64_t *hi, uint64_t *lo)
52
+ {
53
+ ff_uint128_t product = (ff_uint128_t)a * (ff_uint128_t)b;
54
+ *hi = (uint64_t)(product >> 64);
55
+ *lo = (uint64_t)product;
56
+ }
57
+
58
+ #else
59
+ /* Portable 64-bit multiplication */
60
+ static inline void
61
+ mul128(uint64_t a, uint64_t b, uint64_t *hi, uint64_t *lo)
62
+ {
63
+ uint64_t a_lo = (uint32_t)a;
64
+ uint64_t a_hi = a >> 32;
65
+ uint64_t b_lo = (uint32_t)b;
66
+ uint64_t b_hi = b >> 32;
67
+
68
+ uint64_t p0 = a_lo * b_lo;
69
+ uint64_t p1 = a_lo * b_hi;
70
+ uint64_t p2 = a_hi * b_lo;
71
+ uint64_t p3 = a_hi * b_hi;
72
+
73
+ uint64_t middle = p1 + (p0 >> 32) + (uint32_t)p2;
74
+ *hi = p3 + (middle >> 32) + (p2 >> 32);
75
+ *lo = (middle << 32) | (uint32_t)p0;
76
+ }
77
+
78
+ static inline uint64_t
79
+ mul128_upper64(uint64_t a, uint64_t b)
80
+ {
81
+ uint64_t hi, lo;
82
+ mul128(a, b, &hi, &lo);
83
+ return hi;
84
+ }
85
+ #endif
86
+
87
+ /* Count leading zeros */
88
+ static inline int
89
+ clz64(uint64_t x)
90
+ {
91
+ #if defined(__GNUC__) || defined(__clang__)
92
+ return x ? __builtin_clzll(x) : 64;
93
+ #else
94
+ int n = 0;
95
+ if (x == 0) return 64;
96
+ if ((x & 0xFFFFFFFF00000000ULL) == 0) { n += 32; x <<= 32; }
97
+ if ((x & 0xFFFF000000000000ULL) == 0) { n += 16; x <<= 16; }
98
+ if ((x & 0xFF00000000000000ULL) == 0) { n += 8; x <<= 8; }
99
+ if ((x & 0xF000000000000000ULL) == 0) { n += 4; x <<= 4; }
100
+ if ((x & 0xC000000000000000ULL) == 0) { n += 2; x <<= 2; }
101
+ if ((x & 0x8000000000000000ULL) == 0) { n += 1; }
102
+ return n;
103
+ #endif
104
+ }
105
+
106
+ /* ============================================================================
107
+ * Powers of 5 lookup table
108
+ * ============================================================================ */
109
+
110
+ /*
111
+ * Table of 5^q for q in [-342, 308], stored as 128-bit values.
112
+ * Each entry is the 128 most significant bits of 5^q * 2^k for appropriate k.
113
+ */
114
+ static const uint64_t POWERS_OF_FIVE_128[][2] = {
115
+ /* 5^-342 */ {0xeef453d6923bd65aULL, 0x113faa2906a13b3fULL},
116
+ /* 5^-341 */ {0x9558b4661b6565f8ULL, 0x4ac7ca59a424c507ULL},
117
+ /* 5^-340 */ {0xbaaee17fa23ebf76ULL, 0x5d79bcf00d2df649ULL},
118
+ /* 5^-339 */ {0xe95a99df8ace6f53ULL, 0xf4d82c2c107973dcULL},
119
+ /* 5^-338 */ {0x91d8a02bb6c10594ULL, 0x79071b9b8a4be869ULL},
120
+ /* 5^-337 */ {0xb64ec836a47146f9ULL, 0x9748e2826cdee284ULL},
121
+ /* 5^-336 */ {0xe3e27a444d8d98b7ULL, 0xfd1b1b2308169b25ULL},
122
+ /* 5^-335 */ {0x8e6d8c6ab0787f72ULL, 0xfe30f0f5e50e20f7ULL},
123
+ /* 5^-334 */ {0xb208ef855c969f4fULL, 0xbdbd2d335e51a935ULL},
124
+ /* 5^-333 */ {0xde8b2b66b3bc4723ULL, 0xad2c788035e61382ULL},
125
+ /* 5^-332 */ {0x8b16fb203055ac76ULL, 0x4c3bcb5021afcc31ULL},
126
+ /* 5^-331 */ {0xaddcb9e83c6b1793ULL, 0xdf4abe242a1bbf3dULL},
127
+ /* 5^-330 */ {0xd953e8624b85dd78ULL, 0xd71d6dad34a2af0dULL},
128
+ /* 5^-329 */ {0x87d4713d6f33aa6bULL, 0x8672648c40e5ad68ULL},
129
+ /* 5^-328 */ {0xa9c98d8ccb009506ULL, 0x680efdaf511f18c2ULL},
130
+ /* 5^-327 */ {0xd43bf0effdc0ba48ULL, 0x0212bd1b2566def2ULL},
131
+ /* 5^-326 */ {0x84a57695fe98746dULL, 0x014bb630f7604b57ULL},
132
+ /* 5^-325 */ {0xa5ced43b7e3e9188ULL, 0x419ea3bd35385e2dULL},
133
+ /* 5^-324 */ {0xcf42894a5dce35eaULL, 0x52064cac828675b9ULL},
134
+ /* 5^-323 */ {0x818995ce7aa0e1b2ULL, 0x7343efebd1940993ULL},
135
+ /* 5^-322 */ {0xa1ebfb4219491a1fULL, 0x1014ebe6c5f90bf8ULL},
136
+ /* 5^-321 */ {0xca66fa129f9b60a6ULL, 0xd41a26e077774ef6ULL},
137
+ /* 5^-320 */ {0xfd00b897478238d0ULL, 0x8920b098955522b4ULL},
138
+ /* 5^-319 */ {0x9e20735e8cb16382ULL, 0x55b46e5f5d5535b0ULL},
139
+ /* 5^-318 */ {0xc5a890362fddbc62ULL, 0xeb2189f734aa831dULL},
140
+ /* 5^-317 */ {0xf712b443bbd52b7bULL, 0xa5e9ec7501d523e4ULL},
141
+ /* 5^-316 */ {0x9a6bb0aa55653b2dULL, 0x47b233c92125366eULL},
142
+ /* 5^-315 */ {0xc1069cd4eabe89f8ULL, 0x999ec0bb696e840aULL},
143
+ /* 5^-314 */ {0xf148440a256e2c76ULL, 0xc00670ea43ca250dULL},
144
+ /* 5^-313 */ {0x96cd2a865764dbcaULL, 0x380406926a5e5728ULL},
145
+ /* 5^-312 */ {0xbc807527ed3e12bcULL, 0xc605083704f5ecf2ULL},
146
+ /* 5^-311 */ {0xeba09271e88d976bULL, 0xf7864a44c633682eULL},
147
+ /* 5^-310 */ {0x93445b8731587ea3ULL, 0x7ab3ee6afbe0211dULL},
148
+ /* 5^-309 */ {0xb8157268fdae9e4cULL, 0x5960ea05bad82964ULL},
149
+ /* 5^-308 */ {0xe61acf033d1a45dfULL, 0x6fb92487298e33bdULL},
150
+ /* 5^-307 */ {0x8fd0c16206306babULL, 0xa5d3b6d479f8e056ULL},
151
+ /* 5^-306 */ {0xb3c4f1ba87bc8696ULL, 0x8f48a4899877186cULL},
152
+ /* 5^-305 */ {0xe0b62e2929aba83cULL, 0x331acdabfe94de87ULL},
153
+ /* 5^-304 */ {0x8c71dcd9ba0b4925ULL, 0x9ff0c08b7f1d0b14ULL},
154
+ /* 5^-303 */ {0xaf8e5410288e1b6fULL, 0x07ecf0ae5ee44dd9ULL},
155
+ /* 5^-302 */ {0xdb71e91432b1a24aULL, 0xc9e82cd9f69d6150ULL},
156
+ /* 5^-301 */ {0x892731ac9faf056eULL, 0xbe311c083a225cd2ULL},
157
+ /* 5^-300 */ {0xab70fe17c79ac6caULL, 0x6dbd630a48aaf406ULL},
158
+ /* 5^-299 */ {0xd64d3d9db981787dULL, 0x092cbbccdad5b108ULL},
159
+ /* 5^-298 */ {0x85f0468293f0eb4eULL, 0x25bbf56008c58ea5ULL},
160
+ /* 5^-297 */ {0xa76c582338ed2621ULL, 0xaf2af2b80af6f24eULL},
161
+ /* 5^-296 */ {0xd1476e2c07286faaULL, 0x1af5af660db4aee1ULL},
162
+ /* 5^-295 */ {0x82cca4db847945caULL, 0x50d98d9fc890ed4dULL},
163
+ /* 5^-294 */ {0xa37fce126597973cULL, 0xe50ff107bab528a0ULL},
164
+ /* 5^-293 */ {0xcc5fc196fefd7d0cULL, 0x1e53ed49a96272c8ULL},
165
+ /* 5^-292 */ {0xff77b1fcbebcdc4fULL, 0x25e8e89c13bb0f7aULL},
166
+ /* 5^-291 */ {0x9faacf3df73609b1ULL, 0x77b191618c54e9acULL},
167
+ /* 5^-290 */ {0xc795830d75038c1dULL, 0xd59df5b9ef6a2417ULL},
168
+ /* 5^-289 */ {0xf97ae3d0d2446f25ULL, 0x4b0573286b44ad1dULL},
169
+ /* 5^-288 */ {0x9becce62836ac577ULL, 0x4ee367f9430aec32ULL},
170
+ /* 5^-287 */ {0xc2e801fb244576d5ULL, 0x229c41f793cda73fULL},
171
+ /* 5^-286 */ {0xf3a20279ed56d48aULL, 0x6b43527578c1110fULL},
172
+ /* 5^-285 */ {0x9845418c345644d6ULL, 0x830a13896b78aaa9ULL},
173
+ /* 5^-284 */ {0xbe5691ef416bd60cULL, 0x23cc986bc656d553ULL},
174
+ /* 5^-283 */ {0xedec366b11c6cb8fULL, 0x2cbfbe86b7ec8aa8ULL},
175
+ /* 5^-282 */ {0x94b3a202eb1c3f39ULL, 0x7bf7d71432f3d6a9ULL},
176
+ /* 5^-281 */ {0xb9e08a83a5e34f07ULL, 0xdaf5ccd93fb0cc53ULL},
177
+ /* 5^-280 */ {0xe858ad248f5c22c9ULL, 0xd1b3400f8f9cff68ULL},
178
+ /* 5^-279 */ {0x91376c36d99995beULL, 0x23100809b9c21fa1ULL},
179
+ /* 5^-278 */ {0xb58547448ffffb2dULL, 0xabd40a0c2832a78aULL},
180
+ /* 5^-277 */ {0xe2e69915b3fff9f9ULL, 0x16c90c8f323f516cULL},
181
+ /* 5^-276 */ {0x8dd01fad907ffc3bULL, 0xae3da7d97f6792e3ULL},
182
+ /* 5^-275 */ {0xb1442798f49ffb4aULL, 0x99cd11cfdf41779cULL},
183
+ /* 5^-274 */ {0xdd95317f31c7fa1dULL, 0x40405643d711d583ULL},
184
+ /* 5^-273 */ {0x8a7d3eef7f1cfc52ULL, 0x482835ea666b2572ULL},
185
+ /* 5^-272 */ {0xad1c8eab5ee43b66ULL, 0xda3243650005eecfULL},
186
+ /* 5^-271 */ {0xd863b256369d4a40ULL, 0x90bed43e40076a82ULL},
187
+ /* 5^-270 */ {0x873e4f75e2224e68ULL, 0x5a7744a6e804a291ULL},
188
+ /* 5^-269 */ {0xa90de3535aaae202ULL, 0x711515d0a205cb36ULL},
189
+ /* 5^-268 */ {0xd3515c2831559a83ULL, 0x0d5a5b44ca873e03ULL},
190
+ /* 5^-267 */ {0x8412d9991ed58091ULL, 0xe858790afe9486c2ULL},
191
+ /* 5^-266 */ {0xa5178fff668ae0b6ULL, 0x626e974dbe39a872ULL},
192
+ /* 5^-265 */ {0xce5d73ff402d98e3ULL, 0xfb0a3d212dc8128fULL},
193
+ /* 5^-264 */ {0x80fa687f881c7f8eULL, 0x7ce66634bc9d0b99ULL},
194
+ /* 5^-263 */ {0xa139029f6a239f72ULL, 0x1c1fffc1ebc44e80ULL},
195
+ /* 5^-262 */ {0xc987434744ac874eULL, 0xa327ffb266b56220ULL},
196
+ /* 5^-261 */ {0xfbe9141915d7a922ULL, 0x4bf1ff9f0062baa8ULL},
197
+ /* 5^-260 */ {0x9d71ac8fada6c9b5ULL, 0x6f773fc3603db4a9ULL},
198
+ /* 5^-259 */ {0xc4ce17b399107c22ULL, 0xcb550fb4384d21d3ULL},
199
+ /* 5^-258 */ {0xf6019da07f549b2bULL, 0x7e2a53a146606a48ULL},
200
+ /* 5^-257 */ {0x99c102844f94e0fbULL, 0x2eda7444cbfc426dULL},
201
+ /* 5^-256 */ {0xc0314325637a1939ULL, 0xfa911155fefb5308ULL},
202
+ /* 5^-255 */ {0xf03d93eebc589f88ULL, 0x793555ab7eba27caULL},
203
+ /* 5^-254 */ {0x96267c7535b763b5ULL, 0x4bc1558b2f3458deULL},
204
+ /* 5^-253 */ {0xbbb01b9283253ca2ULL, 0x9eb1aaedfb016f16ULL},
205
+ /* 5^-252 */ {0xea9c227723ee8bcbULL, 0x465e15a979c1cadcULL},
206
+ /* 5^-251 */ {0x92a1958a7675175fULL, 0x0bfacd89ec191ec9ULL},
207
+ /* 5^-250 */ {0xb749faed14125d36ULL, 0xcef980ec671f667bULL},
208
+ /* 5^-249 */ {0xe51c79a85916f484ULL, 0x82b7e12780e7401aULL},
209
+ /* 5^-248 */ {0x8f31cc0937ae58d2ULL, 0xd1b2ecb8b0908810ULL},
210
+ /* 5^-247 */ {0xb2fe3f0b8599ef07ULL, 0x861fa7e6dcb4aa15ULL},
211
+ /* 5^-246 */ {0xdfbdcece67006ac9ULL, 0x67a791e093e1d49aULL},
212
+ /* 5^-245 */ {0x8bd6a141006042bdULL, 0xe0c8bb2c5c6d24e0ULL},
213
+ /* 5^-244 */ {0xaecc49914078536dULL, 0x58fae9f773886e18ULL},
214
+ /* 5^-243 */ {0xda7f5bf590966848ULL, 0xaf39a475506a899eULL},
215
+ /* 5^-242 */ {0x888f99797a5e012dULL, 0x6d8406c952429603ULL},
216
+ /* 5^-241 */ {0xaab37fd7d8f58178ULL, 0xc8e5087ba6d33b83ULL},
217
+ /* 5^-240 */ {0xd5605fcdcf32e1d6ULL, 0xfb1e4a9a90880a64ULL},
218
+ /* 5^-239 */ {0x855c3be0a17fcd26ULL, 0x5cf2eea09a55067fULL},
219
+ /* 5^-238 */ {0xa6b34ad8c9dfc06fULL, 0xf42faa48c0ea481eULL},
220
+ /* 5^-237 */ {0xd0601d8efc57b08bULL, 0xf13b94daf124da26ULL},
221
+ /* 5^-236 */ {0x823c12795db6ce57ULL, 0x76c53d08d6b70858ULL},
222
+ /* 5^-235 */ {0xa2cb1717b52481edULL, 0x54768c4b0c64ca6eULL},
223
+ /* 5^-234 */ {0xcb7ddcdda26da268ULL, 0xa9942f5dcf7dfd09ULL},
224
+ /* 5^-233 */ {0xfe5d54150b090b02ULL, 0xd3f93b35435d7c4cULL},
225
+ /* 5^-232 */ {0x9efa548d26e5a6e1ULL, 0xc47bc5014a1a6dafULL},
226
+ /* 5^-231 */ {0xc6b8e9b0709f109aULL, 0x359ab6419ca1091bULL},
227
+ /* 5^-230 */ {0xf867241c8cc6d4c0ULL, 0xc30163d203c94b62ULL},
228
+ /* 5^-229 */ {0x9b407691d7fc44f8ULL, 0x79e0de63425dcf1dULL},
229
+ /* 5^-228 */ {0xc21094364dfb5636ULL, 0x985915fc12f542e4ULL},
230
+ /* 5^-227 */ {0xf294b943e17a2bc4ULL, 0x3e6f5b7b17b2939dULL},
231
+ /* 5^-226 */ {0x979cf3ca6cec5b5aULL, 0xa705992ceecf9c42ULL},
232
+ /* 5^-225 */ {0xbd8430bd08277231ULL, 0x50c6ff782a838353ULL},
233
+ /* 5^-224 */ {0xece53cec4a314ebdULL, 0xa4f8bf5635246428ULL},
234
+ /* 5^-223 */ {0x940f4613ae5ed136ULL, 0x871b7795e136be99ULL},
235
+ /* 5^-222 */ {0xb913179899f68584ULL, 0x28e2557b59846e3fULL},
236
+ /* 5^-221 */ {0xe757dd7ec07426e5ULL, 0x331aeada2fe589cfULL},
237
+ /* 5^-220 */ {0x9096ea6f3848984fULL, 0x3ff0d2c85def7621ULL},
238
+ /* 5^-219 */ {0xb4bca50b065abe63ULL, 0x0fed077a756b53a9ULL},
239
+ /* 5^-218 */ {0xe1ebce4dc7f16dfbULL, 0xd3e8495912c62894ULL},
240
+ /* 5^-217 */ {0x8d3360f09cf6e4bdULL, 0x64712dd7abbbd95cULL},
241
+ /* 5^-216 */ {0xb080392cc4349decULL, 0xbd8d794d96aacfb3ULL},
242
+ /* 5^-215 */ {0xdca04777f541c567ULL, 0xecf0d7a0fc5583a0ULL},
243
+ /* 5^-214 */ {0x89e42caaf9491b60ULL, 0xf41686c49db57244ULL},
244
+ /* 5^-213 */ {0xac5d37d5b79b6239ULL, 0x311c2875c522ced5ULL},
245
+ /* 5^-212 */ {0xd77485cb25823ac7ULL, 0x7d633293366b828bULL},
246
+ /* 5^-211 */ {0x86a8d39ef77164bcULL, 0xae5dff9c02033197ULL},
247
+ /* 5^-210 */ {0xa8530886b54dbdebULL, 0xd9f57f830283fdfdULL},
248
+ /* 5^-209 */ {0xd267caa862a12d66ULL, 0xd072df63c324fd7bULL},
249
+ /* 5^-208 */ {0x8380dea93da4bc60ULL, 0x4247cb9e59f71e6dULL},
250
+ /* 5^-207 */ {0xa46116538d0deb78ULL, 0x52d9be85f074e608ULL},
251
+ /* 5^-206 */ {0xcd795be870516656ULL, 0x67902e276c921f8bULL},
252
+ /* 5^-205 */ {0x806bd9714632dff6ULL, 0x00ba1cd8a3db53b6ULL},
253
+ /* 5^-204 */ {0xa086cfcd97bf97f3ULL, 0x80e8a40eccd228a4ULL},
254
+ /* 5^-203 */ {0xc8a883c0fdaf7df0ULL, 0x6122cd128006b2cdULL},
255
+ /* 5^-202 */ {0xfad2a4b13d1b5d6cULL, 0x796b805720085f81ULL},
256
+ /* 5^-201 */ {0x9cc3a6eec6311a63ULL, 0xcbe3303674053bb0ULL},
257
+ /* 5^-200 */ {0xc3f490aa77bd60fcULL, 0xbedbfc4411068a9cULL},
258
+ /* 5^-199 */ {0xf4f1b4d515acb93bULL, 0xee92fb5515482d44ULL},
259
+ /* 5^-198 */ {0x991711052d8bf3c5ULL, 0x751bdd152d4d1c4aULL},
260
+ /* 5^-197 */ {0xbf5cd54678eef0b6ULL, 0xd262d45a78a0635dULL},
261
+ /* 5^-196 */ {0xef340a98172aace4ULL, 0x86fb897116c87c34ULL},
262
+ /* 5^-195 */ {0x9580869f0e7aac0eULL, 0xd45d35e6ae3d4da0ULL},
263
+ /* 5^-194 */ {0xbae0a846d2195712ULL, 0x8974836059cca109ULL},
264
+ /* 5^-193 */ {0xe998d258869facd7ULL, 0x2bd1a438703fc94bULL},
265
+ /* 5^-192 */ {0x91ff83775423cc06ULL, 0x7b6306a34627ddcfULL},
266
+ /* 5^-191 */ {0xb67f6455292cbf08ULL, 0x1a3bc84c17b1d542ULL},
267
+ /* 5^-190 */ {0xe41f3d6a7377eecaULL, 0x20caba5f1d9e4a93ULL},
268
+ /* 5^-189 */ {0x8e938662882af53eULL, 0x547eb47b7282ee9cULL},
269
+ /* 5^-188 */ {0xb23867fb2a35b28dULL, 0xe99e619a4f23aa43ULL},
270
+ /* 5^-187 */ {0xdec681f9f4c31f31ULL, 0x6405fa00e2ec94d4ULL},
271
+ /* 5^-186 */ {0x8b3c113c38f9f37eULL, 0xde83bc408dd3dd04ULL},
272
+ /* 5^-185 */ {0xae0b158b4738705eULL, 0x9624ab50b148d445ULL},
273
+ /* 5^-184 */ {0xd98ddaee19068c76ULL, 0x3badd624dd9b0957ULL},
274
+ /* 5^-183 */ {0x87f8a8d4cfa417c9ULL, 0xe54ca5d70a80e5d6ULL},
275
+ /* 5^-182 */ {0xa9f6d30a038d1dbcULL, 0x5e9fcf4ccd211f4cULL},
276
+ /* 5^-181 */ {0xd47487cc8470652bULL, 0x7647c3200069671fULL},
277
+ /* 5^-180 */ {0x84c8d4dfd2c63f3bULL, 0x29ecd9f40041e073ULL},
278
+ /* 5^-179 */ {0xa5fb0a17c777cf09ULL, 0xf468107100525890ULL},
279
+ /* 5^-178 */ {0xcf79cc9db955c2ccULL, 0x7182148d4066eeb4ULL},
280
+ /* 5^-177 */ {0x81ac1fe293d599bfULL, 0xc6f14cd848405530ULL},
281
+ /* 5^-176 */ {0xa21727db38cb002fULL, 0xb8ada00e5a506a7cULL},
282
+ /* 5^-175 */ {0xca9cf1d206fdc03bULL, 0xa6d90811f0e4851cULL},
283
+ /* 5^-174 */ {0xfd442e4688bd304aULL, 0x908f4a166d1da663ULL},
284
+ /* 5^-173 */ {0x9e4a9cec15763e2eULL, 0x9a598e4e043287feULL},
285
+ /* 5^-172 */ {0xc5dd44271ad3cdbaULL, 0x40eff1e1853f29fdULL},
286
+ /* 5^-171 */ {0xf7549530e188c128ULL, 0xd12bee59e68ef47cULL},
287
+ /* 5^-170 */ {0x9a94dd3e8cf578b9ULL, 0x82bb74f8301958ceULL},
288
+ /* 5^-169 */ {0xc13a148e3032d6e7ULL, 0xe36a52363c1faf01ULL},
289
+ /* 5^-168 */ {0xf18899b1bc3f8ca1ULL, 0xdc44e6c3cb279ac1ULL},
290
+ /* 5^-167 */ {0x96f5600f15a7b7e5ULL, 0x29ab103a5ef8c0b9ULL},
291
+ /* 5^-166 */ {0xbcb2b812db11a5deULL, 0x7415d448f6b6f0e7ULL},
292
+ /* 5^-165 */ {0xebdf661791d60f56ULL, 0x111b495b3464ad21ULL},
293
+ /* 5^-164 */ {0x936b9fcebb25c995ULL, 0xcab10dd900beec34ULL},
294
+ /* 5^-163 */ {0xb84687c269ef3bfbULL, 0x3d5d514f40eea742ULL},
295
+ /* 5^-162 */ {0xe65829b3046b0afaULL, 0x0cb4a5a3112a5112ULL},
296
+ /* 5^-161 */ {0x8ff71a0fe2c2e6dcULL, 0x47f0e785eaba72abULL},
297
+ /* 5^-160 */ {0xb3f4e093db73a093ULL, 0x59ed216765690f56ULL},
298
+ /* 5^-159 */ {0xe0f218b8d25088b8ULL, 0x306869c13ec3532cULL},
299
+ /* 5^-158 */ {0x8c974f7383725573ULL, 0x1e414218c73a13fbULL},
300
+ /* 5^-157 */ {0xafbd2350644eeacfULL, 0xe5d1929ef90898faULL},
301
+ /* 5^-156 */ {0xdbac6c247d62a583ULL, 0xdf45f746b74abf39ULL},
302
+ /* 5^-155 */ {0x894bc396ce5da772ULL, 0x6b8bba8c328eb783ULL},
303
+ /* 5^-154 */ {0xab9eb47c81f5114fULL, 0x066ea92f3f326564ULL},
304
+ /* 5^-153 */ {0xd686619ba27255a2ULL, 0xc80a537b0efefebdULL},
305
+ /* 5^-152 */ {0x8613fd0145877585ULL, 0xbd06742ce95f5f36ULL},
306
+ /* 5^-151 */ {0xa798fc4196e952e7ULL, 0x2c48113823b73704ULL},
307
+ /* 5^-150 */ {0xd17f3b51fca3a7a0ULL, 0xf75a15862ca504c5ULL},
308
+ /* 5^-149 */ {0x82ef85133de648c4ULL, 0x9a984d73dbe722fbULL},
309
+ /* 5^-148 */ {0xa3ab66580d5fdaf5ULL, 0xc13e60d0d2e0ebbaULL},
310
+ /* 5^-147 */ {0xcc963fee10b7d1b3ULL, 0x318df905079926a8ULL},
311
+ /* 5^-146 */ {0xffbbcfe994e5c61fULL, 0xfdf17746497f7052ULL},
312
+ /* 5^-145 */ {0x9fd561f1fd0f9bd3ULL, 0xfeb6ea8bedefa633ULL},
313
+ /* 5^-144 */ {0xc7caba6e7c5382c8ULL, 0xfe64a52ee96b8fc0ULL},
314
+ /* 5^-143 */ {0xf9bd690a1b68637bULL, 0x3dfdce7aa3c673b0ULL},
315
+ /* 5^-142 */ {0x9c1661a651213e2dULL, 0x06bea10ca65c084eULL},
316
+ /* 5^-141 */ {0xc31bfa0fe5698db8ULL, 0x486e494fcff30a62ULL},
317
+ /* 5^-140 */ {0xf3e2f893dec3f126ULL, 0x5a89dba3c3efccfaULL},
318
+ /* 5^-139 */ {0x986ddb5c6b3a76b7ULL, 0xf89629465a75e01cULL},
319
+ /* 5^-138 */ {0xbe89523386091465ULL, 0xf6bbb397f1135823ULL},
320
+ /* 5^-137 */ {0xee2ba6c0678b597fULL, 0x746aa07ded582e2cULL},
321
+ /* 5^-136 */ {0x94db483840b717efULL, 0xa8c2a44eb4571cdcULL},
322
+ /* 5^-135 */ {0xba121a4650e4ddebULL, 0x92f34d62616ce413ULL},
323
+ /* 5^-134 */ {0xe896a0d7e51e1566ULL, 0x77b020baf9c81d17ULL},
324
+ /* 5^-133 */ {0x915e2486ef32cd60ULL, 0x0ace1474dc1d122eULL},
325
+ /* 5^-132 */ {0xb5b5ada8aaff80b8ULL, 0x0d819992132456baULL},
326
+ /* 5^-131 */ {0xe3231912d5bf60e6ULL, 0x10e1fff697ed6c69ULL},
327
+ /* 5^-130 */ {0x8df5efabc5979c8fULL, 0xca8d3ffa1ef463c1ULL},
328
+ /* 5^-129 */ {0xb1736b96b6fd83b3ULL, 0xbd308ff8a6b17cb2ULL},
329
+ /* 5^-128 */ {0xddd0467c64bce4a0ULL, 0xac7cb3f6d05ddbdeULL},
330
+ /* 5^-127 */ {0x8aa22c0dbef60ee4ULL, 0x6bcdf07a423aa96bULL},
331
+ /* 5^-126 */ {0xad4ab7112eb3929dULL, 0x86c16c98d2c953c6ULL},
332
+ /* 5^-125 */ {0xd89d64d57a607744ULL, 0xe871c7bf077ba8b7ULL},
333
+ /* 5^-124 */ {0x87625f056c7c4a8bULL, 0x11471cd764ad4972ULL},
334
+ /* 5^-123 */ {0xa93af6c6c79b5d2dULL, 0xd598e40d3dd89bcfULL},
335
+ /* 5^-122 */ {0xd389b47879823479ULL, 0x4aff1d108d4ec2c3ULL},
336
+ /* 5^-121 */ {0x843610cb4bf160cbULL, 0xcedf722a585139baULL},
337
+ /* 5^-120 */ {0xa54394fe1eedb8feULL, 0xc2974eb4ee658828ULL},
338
+ /* 5^-119 */ {0xce947a3da6a9273eULL, 0x733d226229feea32ULL},
339
+ /* 5^-118 */ {0x811ccc668829b887ULL, 0x0806357d5a3f525fULL},
340
+ /* 5^-117 */ {0xa163ff802a3426a8ULL, 0xca07c2dcb0cf26f7ULL},
341
+ /* 5^-116 */ {0xc9bcff6034c13052ULL, 0xfc89b393dd02f0b5ULL},
342
+ /* 5^-115 */ {0xfc2c3f3841f17c67ULL, 0xbbac2078d443ace2ULL},
343
+ /* 5^-114 */ {0x9d9ba7832936edc0ULL, 0xd54b944b84aa4c0dULL},
344
+ /* 5^-113 */ {0xc5029163f384a931ULL, 0x0a9e795e65d4df11ULL},
345
+ /* 5^-112 */ {0xf64335bcf065d37dULL, 0x4d4617b5ff4a16d5ULL},
346
+ /* 5^-111 */ {0x99ea0196163fa42eULL, 0x504bced1bf8e4e45ULL},
347
+ /* 5^-110 */ {0xc06481fb9bcf8d39ULL, 0xe45ec2862f71e1d6ULL},
348
+ /* 5^-109 */ {0xf07da27a82c37088ULL, 0x5d767327bb4e5a4cULL},
349
+ /* 5^-108 */ {0x964e858c91ba2655ULL, 0x3a6a07f8d510f86fULL},
350
+ /* 5^-107 */ {0xbbe226efb628afaaULL, 0x890489f70a55368bULL},
351
+ /* 5^-106 */ {0xeadab0aba3b2dbe5ULL, 0x2b45ac74ccea842eULL},
352
+ /* 5^-105 */ {0x92c8ae6b464fc96fULL, 0x3b0b8bc90012929dULL},
353
+ /* 5^-104 */ {0xb77ada0617e3bbcbULL, 0x09ce6ebb40173744ULL},
354
+ /* 5^-103 */ {0xe55990879ddcaabdULL, 0xcc420a6a101d0515ULL},
355
+ /* 5^-102 */ {0x8f57fa54c2a9eab6ULL, 0x9fa946824a12232dULL},
356
+ /* 5^-101 */ {0xb32df8e9f3546564ULL, 0x47939822dc96abf9ULL},
357
+ /* 5^-100 */ {0xdff9772470297ebdULL, 0x59787e2b93bc56f7ULL},
358
+ /* 5^-99 */ {0x8bfbea76c619ef36ULL, 0x57eb4edb3c55b65aULL},
359
+ /* 5^-98 */ {0xaefae51477a06b03ULL, 0xede622920b6b23f1ULL},
360
+ /* 5^-97 */ {0xdab99e59958885c4ULL, 0xe95fab368e45ecedULL},
361
+ /* 5^-96 */ {0x88b402f7fd75539bULL, 0x11dbcb0218ebb414ULL},
362
+ /* 5^-95 */ {0xaae103b5fcd2a881ULL, 0xd652bdc29f26a119ULL},
363
+ /* 5^-94 */ {0xd59944a37c0752a2ULL, 0x4be76d3346f0495fULL},
364
+ /* 5^-93 */ {0x857fcae62d8493a5ULL, 0x6f70a4400c562ddbULL},
365
+ /* 5^-92 */ {0xa6dfbd9fb8e5b88eULL, 0xcb4ccd500f6bb952ULL},
366
+ /* 5^-91 */ {0xd097ad07a71f26b2ULL, 0x7e2000a41346a7a7ULL},
367
+ /* 5^-90 */ {0x825ecc24c873782fULL, 0x8ed400668c0c28c8ULL},
368
+ /* 5^-89 */ {0xa2f67f2dfa90563bULL, 0x728900802f0f32faULL},
369
+ /* 5^-88 */ {0xcbb41ef979346bcaULL, 0x4f2b40a03ad2ffb9ULL},
370
+ /* 5^-87 */ {0xfea126b7d78186bcULL, 0xe2f610c84987bfa8ULL},
371
+ /* 5^-86 */ {0x9f24b832e6b0f436ULL, 0x0dd9ca7d2df4d7c9ULL},
372
+ /* 5^-85 */ {0xc6ede63fa05d3143ULL, 0x91503d1c79720dbbULL},
373
+ /* 5^-84 */ {0xf8a95fcf88747d94ULL, 0x75a44c6397ce912aULL},
374
+ /* 5^-83 */ {0x9b69dbe1b548ce7cULL, 0xc986afbe3ee11abaULL},
375
+ /* 5^-82 */ {0xc24452da229b021bULL, 0xfbe85badce996168ULL},
376
+ /* 5^-81 */ {0xf2d56790ab41c2a2ULL, 0xfae27299423fb9c3ULL},
377
+ /* 5^-80 */ {0x97c560ba6b0919a5ULL, 0xdccd879fc967d41aULL},
378
+ /* 5^-79 */ {0xbdb6b8e905cb600fULL, 0x5400e987bbc1c920ULL},
379
+ /* 5^-78 */ {0xed246723473e3813ULL, 0x290123e9aab23b68ULL},
380
+ /* 5^-77 */ {0x9436c0760c86e30bULL, 0xf9a0b6720aaf6521ULL},
381
+ /* 5^-76 */ {0xb94470938fa89bceULL, 0xf808e40e8d5b3e69ULL},
382
+ /* 5^-75 */ {0xe7958cb87392c2c2ULL, 0xb60b1d1230b20e04ULL},
383
+ /* 5^-74 */ {0x90bd77f3483bb9b9ULL, 0xb1c6f22b5e6f48c2ULL},
384
+ /* 5^-73 */ {0xb4ecd5f01a4aa828ULL, 0x1e38aeb6360b1af3ULL},
385
+ /* 5^-72 */ {0xe2280b6c20dd5232ULL, 0x25c6da63c38de1b0ULL},
386
+ /* 5^-71 */ {0x8d590723948a535fULL, 0x579c487e5a38ad0eULL},
387
+ /* 5^-70 */ {0xb0af48ec79ace837ULL, 0x2d835a9df0c6d851ULL},
388
+ /* 5^-69 */ {0xdcdb1b2798182244ULL, 0xf8e431456cf88e65ULL},
389
+ /* 5^-68 */ {0x8a08f0f8bf0f156bULL, 0x1b8e9ecb641b58ffULL},
390
+ /* 5^-67 */ {0xac8b2d36eed2dac5ULL, 0xe272467e3d222f3fULL},
391
+ /* 5^-66 */ {0xd7adf884aa879177ULL, 0x5b0ed81dcc6abb0fULL},
392
+ /* 5^-65 */ {0x86ccbb52ea94baeaULL, 0x98e947129fc2b4e9ULL},
393
+ /* 5^-64 */ {0xa87fea27a539e9a5ULL, 0x3f2398d747b36224ULL},
394
+ /* 5^-63 */ {0xd29fe4b18e88640eULL, 0x8eec7f0d19a03aadULL},
395
+ /* 5^-62 */ {0x83a3eeeef9153e89ULL, 0x1953cf68300424acULL},
396
+ /* 5^-61 */ {0xa48ceaaab75a8e2bULL, 0x5fa8c3423c052dd7ULL},
397
+ /* 5^-60 */ {0xcdb02555653131b6ULL, 0x3792f412cb06794dULL},
398
+ /* 5^-59 */ {0x808e17555f3ebf11ULL, 0xe2bbd88bbee40bd0ULL},
399
+ /* 5^-58 */ {0xa0b19d2ab70e6ed6ULL, 0x5b6aceaeae9d0ec4ULL},
400
+ /* 5^-57 */ {0xc8de047564d20a8bULL, 0xf245825a5a445275ULL},
401
+ /* 5^-56 */ {0xfb158592be068d2eULL, 0xeed6e2f0f0d56712ULL},
402
+ /* 5^-55 */ {0x9ced737bb6c4183dULL, 0x55464dd69685606bULL},
403
+ /* 5^-54 */ {0xc428d05aa4751e4cULL, 0xaa97e14c3c26b886ULL},
404
+ /* 5^-53 */ {0xf53304714d9265dfULL, 0xd53dd99f4b3066a8ULL},
405
+ /* 5^-52 */ {0x993fe2c6d07b7fabULL, 0xe546a8038efe4029ULL},
406
+ /* 5^-51 */ {0xbf8fdb78849a5f96ULL, 0xde98520472bdd033ULL},
407
+ /* 5^-50 */ {0xef73d256a5c0f77cULL, 0x963e66858f6d4440ULL},
408
+ /* 5^-49 */ {0x95a8637627989aadULL, 0xdde7001379a44aa8ULL},
409
+ /* 5^-48 */ {0xbb127c53b17ec159ULL, 0x5560c018580d5d52ULL},
410
+ /* 5^-47 */ {0xe9d71b689dde71afULL, 0xaab8f01e6e10b4a6ULL},
411
+ /* 5^-46 */ {0x9226712162ab070dULL, 0xcab3961304ca70e8ULL},
412
+ /* 5^-45 */ {0xb6b00d69bb55c8d1ULL, 0x3d607b97c5fd0d22ULL},
413
+ /* 5^-44 */ {0xe45c10c42a2b3b05ULL, 0x8cb89a7db77c506aULL},
414
+ /* 5^-43 */ {0x8eb98a7a9a5b04e3ULL, 0x77f3608e92adb242ULL},
415
+ /* 5^-42 */ {0xb267ed1940f1c61cULL, 0x55f038b237591ed3ULL},
416
+ /* 5^-41 */ {0xdf01e85f912e37a3ULL, 0x6b6c46dec52f6688ULL},
417
+ /* 5^-40 */ {0x8b61313bbabce2c6ULL, 0x2323ac4b3b3da015ULL},
418
+ /* 5^-39 */ {0xae397d8aa96c1b77ULL, 0xabec975e0a0d081aULL},
419
+ /* 5^-38 */ {0xd9c7dced53c72255ULL, 0x96e7bd358c904a21ULL},
420
+ /* 5^-37 */ {0x881cea14545c7575ULL, 0x7e50d64177da2e54ULL},
421
+ /* 5^-36 */ {0xaa242499697392d2ULL, 0xdde50bd1d5d0b9e9ULL},
422
+ /* 5^-35 */ {0xd4ad2dbfc3d07787ULL, 0x955e4ec64b44e864ULL},
423
+ /* 5^-34 */ {0x84ec3c97da624ab4ULL, 0xbd5af13bef0b113eULL},
424
+ /* 5^-33 */ {0xa6274bbdd0fadd61ULL, 0xecb1ad8aeacdd58eULL},
425
+ /* 5^-32 */ {0xcfb11ead453994baULL, 0x67de18eda5814af2ULL},
426
+ /* 5^-31 */ {0x81ceb32c4b43fcf4ULL, 0x80eacf948770ced7ULL},
427
+ /* 5^-30 */ {0xa2425ff75e14fc31ULL, 0xa1258379a94d028dULL},
428
+ /* 5^-29 */ {0xcad2f7f5359a3b3eULL, 0x096ee45813a04330ULL},
429
+ /* 5^-28 */ {0xfd87b5f28300ca0dULL, 0x8bca9d6e188853fcULL},
430
+ /* 5^-27 */ {0x9e74d1b791e07e48ULL, 0x775ea264cf55347dULL},
431
+ /* 5^-26 */ {0xc612062576589ddaULL, 0x95364afe032a819dULL},
432
+ /* 5^-25 */ {0xf79687aed3eec551ULL, 0x3a83ddbd83f52204ULL},
433
+ /* 5^-24 */ {0x9abe14cd44753b52ULL, 0xc4926a9672793542ULL},
434
+ /* 5^-23 */ {0xc16d9a0095928a27ULL, 0x75b7053c0f178293ULL},
435
+ /* 5^-22 */ {0xf1c90080baf72cb1ULL, 0x5324c68b12dd6338ULL},
436
+ /* 5^-21 */ {0x971da05074da7beeULL, 0xd3f6fc16ebca5e03ULL},
437
+ /* 5^-20 */ {0xbce5086492111aeaULL, 0x88f4bb1ca6bcf584ULL},
438
+ /* 5^-19 */ {0xec1e4a7db69561a5ULL, 0x2b31e9e3d06c32e5ULL},
439
+ /* 5^-18 */ {0x9392ee8e921d5d07ULL, 0x3aff322e62439fcfULL},
440
+ /* 5^-17 */ {0xb877aa3236a4b449ULL, 0x09befeb9fad487c2ULL},
441
+ /* 5^-16 */ {0xe69594bec44de15bULL, 0x4c2ebe687989a9b3ULL},
442
+ /* 5^-15 */ {0x901d7cf73ab0acd9ULL, 0x0f9d37014bf60a10ULL},
443
+ /* 5^-14 */ {0xb424dc35095cd80fULL, 0x538484c19ef38c94ULL},
444
+ /* 5^-13 */ {0xe12e13424bb40e13ULL, 0x2865a5f206b06fb9ULL},
445
+ /* 5^-12 */ {0x8cbccc096f5088cbULL, 0xf93f87b7442e45d3ULL},
446
+ /* 5^-11 */ {0xafebff0bcb24aafeULL, 0xf78f69a51539d748ULL},
447
+ /* 5^-10 */ {0xdbe6fecebdedd5beULL, 0xb573440e5a884d1bULL},
448
+ /* 5^-9 */ {0x89705f4136b4a597ULL, 0x31680a88f8953030ULL},
449
+ /* 5^-8 */ {0xabcc77118461cefcULL, 0xfdc20d2b36ba7c3dULL},
450
+ /* 5^-7 */ {0xd6bf94d5e57a42bcULL, 0x3d32907604691b4cULL},
451
+ /* 5^-6 */ {0x8637bd05af6c69b5ULL, 0xa63f9a49c2c1b10fULL},
452
+ /* 5^-5 */ {0xa7c5ac471b478423ULL, 0x0fcf80dc33721d53ULL},
453
+ /* 5^-4 */ {0xd1b71758e219652bULL, 0xd3c36113404ea4a8ULL},
454
+ /* 5^-3 */ {0x83126e978d4fdf3bULL, 0x645a1cac083126e9ULL},
455
+ /* 5^-2 */ {0xa3d70a3d70a3d70aULL, 0x3d70a3d70a3d70a3ULL},
456
+ /* 5^-1 */ {0xccccccccccccccccULL, 0xccccccccccccccccULL},
457
+ /* 5^0 */ {0x8000000000000000ULL, 0x0000000000000000ULL},
458
+ /* 5^1 */ {0xa000000000000000ULL, 0x0000000000000000ULL},
459
+ /* 5^2 */ {0xc800000000000000ULL, 0x0000000000000000ULL},
460
+ /* 5^3 */ {0xfa00000000000000ULL, 0x0000000000000000ULL},
461
+ /* 5^4 */ {0x9c40000000000000ULL, 0x0000000000000000ULL},
462
+ /* 5^5 */ {0xc350000000000000ULL, 0x0000000000000000ULL},
463
+ /* 5^6 */ {0xf424000000000000ULL, 0x0000000000000000ULL},
464
+ /* 5^7 */ {0x9896800000000000ULL, 0x0000000000000000ULL},
465
+ /* 5^8 */ {0xbebc200000000000ULL, 0x0000000000000000ULL},
466
+ /* 5^9 */ {0xee6b280000000000ULL, 0x0000000000000000ULL},
467
+ /* 5^10 */ {0x9502f90000000000ULL, 0x0000000000000000ULL},
468
+ /* 5^11 */ {0xba43b74000000000ULL, 0x0000000000000000ULL},
469
+ /* 5^12 */ {0xe8d4a51000000000ULL, 0x0000000000000000ULL},
470
+ /* 5^13 */ {0x9184e72a00000000ULL, 0x0000000000000000ULL},
471
+ /* 5^14 */ {0xb5e620f480000000ULL, 0x0000000000000000ULL},
472
+ /* 5^15 */ {0xe35fa931a0000000ULL, 0x0000000000000000ULL},
473
+ /* 5^16 */ {0x8e1bc9bf04000000ULL, 0x0000000000000000ULL},
474
+ /* 5^17 */ {0xb1a2bc2ec5000000ULL, 0x0000000000000000ULL},
475
+ /* 5^18 */ {0xde0b6b3a76400000ULL, 0x0000000000000000ULL},
476
+ /* 5^19 */ {0x8ac7230489e80000ULL, 0x0000000000000000ULL},
477
+ /* 5^20 */ {0xad78ebc5ac620000ULL, 0x0000000000000000ULL},
478
+ /* 5^21 */ {0xd8d726b7177a8000ULL, 0x0000000000000000ULL},
479
+ /* 5^22 */ {0x878678326eac9000ULL, 0x0000000000000000ULL},
480
+ /* 5^23 */ {0xa968163f0a57b400ULL, 0x0000000000000000ULL},
481
+ /* 5^24 */ {0xd3c21bcecceda100ULL, 0x0000000000000000ULL},
482
+ /* 5^25 */ {0x84595161401484a0ULL, 0x0000000000000000ULL},
483
+ /* 5^26 */ {0xa56fa5b99019a5c8ULL, 0x0000000000000000ULL},
484
+ /* 5^27 */ {0xcecb8f27f4200f3aULL, 0x0000000000000000ULL},
485
+ /* 5^28 */ {0x813f3978f8940984ULL, 0x4000000000000000ULL},
486
+ /* 5^29 */ {0xa18f07d736b90be5ULL, 0x5000000000000000ULL},
487
+ /* 5^30 */ {0xc9f2c9cd04674edeULL, 0xa400000000000000ULL},
488
+ /* 5^31 */ {0xfc6f7c4045812296ULL, 0x4d00000000000000ULL},
489
+ /* 5^32 */ {0x9dc5ada82b70b59dULL, 0xf020000000000000ULL},
490
+ /* 5^33 */ {0xc5371912364ce305ULL, 0x6c28000000000000ULL},
491
+ /* 5^34 */ {0xf684df56c3e01bc6ULL, 0xc732000000000000ULL},
492
+ /* 5^35 */ {0x9a130b963a6c115cULL, 0x3c7f400000000000ULL},
493
+ /* 5^36 */ {0xc097ce7bc90715b3ULL, 0x4b9f100000000000ULL},
494
+ /* 5^37 */ {0xf0bdc21abb48db20ULL, 0x1e86d40000000000ULL},
495
+ /* 5^38 */ {0x96769950b50d88f4ULL, 0x1314448000000000ULL},
496
+ /* 5^39 */ {0xbc143fa4e250eb31ULL, 0x17d955a000000000ULL},
497
+ /* 5^40 */ {0xeb194f8e1ae525fdULL, 0x5dcfab0800000000ULL},
498
+ /* 5^41 */ {0x92efd1b8d0cf37beULL, 0x5aa1cae500000000ULL},
499
+ /* 5^42 */ {0xb7abc627050305adULL, 0xf14a3d9e40000000ULL},
500
+ /* 5^43 */ {0xe596b7b0c643c719ULL, 0x6d9ccd05d0000000ULL},
501
+ /* 5^44 */ {0x8f7e32ce7bea5c6fULL, 0xe4820023a2000000ULL},
502
+ /* 5^45 */ {0xb35dbf821ae4f38bULL, 0xdda2802c8a800000ULL},
503
+ /* 5^46 */ {0xe0352f62a19e306eULL, 0xd50b2037ad200000ULL},
504
+ /* 5^47 */ {0x8c213d9da502de45ULL, 0x4526f422cc340000ULL},
505
+ /* 5^48 */ {0xaf298d050e4395d6ULL, 0x9670b12b7f410000ULL},
506
+ /* 5^49 */ {0xdaf3f04651d47b4cULL, 0x3c0cdd765f114000ULL},
507
+ /* 5^50 */ {0x88d8762bf324cd0fULL, 0xa5880a69fb6ac800ULL},
508
+ /* 5^51 */ {0xab0e93b6efee0053ULL, 0x8eea0d047a457a00ULL},
509
+ /* 5^52 */ {0xd5d238a4abe98068ULL, 0x72a4904598d6d880ULL},
510
+ /* 5^53 */ {0x85a36366eb71f041ULL, 0x47a6da2b7f864750ULL},
511
+ /* 5^54 */ {0xa70c3c40a64e6c51ULL, 0x999090b65f67d924ULL},
512
+ /* 5^55 */ {0xd0cf4b50cfe20765ULL, 0xfff4b4e3f741cf6dULL},
513
+ /* 5^56 */ {0x82818f1281ed449fULL, 0xbff8f10e7a8921a4ULL},
514
+ /* 5^57 */ {0xa321f2d7226895c7ULL, 0xaff72d52192b6a0dULL},
515
+ /* 5^58 */ {0xcbea6f8ceb02bb39ULL, 0x9bf4f8a69f764490ULL},
516
+ /* 5^59 */ {0xfee50b7025c36a08ULL, 0x02f236d04753d5b4ULL},
517
+ /* 5^60 */ {0x9f4f2726179a2245ULL, 0x01d762422c946590ULL},
518
+ /* 5^61 */ {0xc722f0ef9d80aad6ULL, 0x424d3ad2b7b97ef5ULL},
519
+ /* 5^62 */ {0xf8ebad2b84e0d58bULL, 0xd2e0898765a7deb2ULL},
520
+ /* 5^63 */ {0x9b934c3b330c8577ULL, 0x63cc55f49f88eb2fULL},
521
+ /* 5^64 */ {0xc2781f49ffcfa6d5ULL, 0x3cbf6b71c76b25fbULL},
522
+ /* 5^65 */ {0xf316271c7fc3908aULL, 0x8bef464e3945ef7aULL},
523
+ /* 5^66 */ {0x97edd871cfda3a56ULL, 0x97758bf0e3cbb5acULL},
524
+ /* 5^67 */ {0xbde94e8e43d0c8ecULL, 0x3d52eeed1cbea317ULL},
525
+ /* 5^68 */ {0xed63a231d4c4fb27ULL, 0x4ca7aaa863ee4bddULL},
526
+ /* 5^69 */ {0x945e455f24fb1cf8ULL, 0x8fe8caa93e74ef6aULL},
527
+ /* 5^70 */ {0xb975d6b6ee39e436ULL, 0xb3e2fd538e122b44ULL},
528
+ /* 5^71 */ {0xe7d34c64a9c85d44ULL, 0x60dbbca87196b616ULL},
529
+ /* 5^72 */ {0x90e40fbeea1d3a4aULL, 0xbc8955e946fe31cdULL},
530
+ /* 5^73 */ {0xb51d13aea4a488ddULL, 0x6babab6398bdbe41ULL},
531
+ /* 5^74 */ {0xe264589a4dcdab14ULL, 0xc696963c7eed2dd1ULL},
532
+ /* 5^75 */ {0x8d7eb76070a08aecULL, 0xfc1e1de5cf543ca2ULL},
533
+ /* 5^76 */ {0xb0de65388cc8ada8ULL, 0x3b25a55f43294bcbULL},
534
+ /* 5^77 */ {0xdd15fe86affad912ULL, 0x49ef0eb713f39ebeULL},
535
+ /* 5^78 */ {0x8a2dbf142dfcc7abULL, 0x6e3569326c784337ULL},
536
+ /* 5^79 */ {0xacb92ed9397bf996ULL, 0x49c2c37f07965404ULL},
537
+ /* 5^80 */ {0xd7e77a8f87daf7fbULL, 0xdc33745ec97be906ULL},
538
+ /* 5^81 */ {0x86f0ac99b4e8dafdULL, 0x69a028bb3ded71a3ULL},
539
+ /* 5^82 */ {0xa8acd7c0222311bcULL, 0xc40832ea0d68ce0cULL},
540
+ /* 5^83 */ {0xd2d80db02aabd62bULL, 0xf50a3fa490c30190ULL},
541
+ /* 5^84 */ {0x83c7088e1aab65dbULL, 0x792667c6da79e0faULL},
542
+ /* 5^85 */ {0xa4b8cab1a1563f52ULL, 0x577001b891185938ULL},
543
+ /* 5^86 */ {0xcde6fd5e09abcf26ULL, 0xed4c0226b55e6f86ULL},
544
+ /* 5^87 */ {0x80b05e5ac60b6178ULL, 0x544f8158315b05b4ULL},
545
+ /* 5^88 */ {0xa0dc75f1778e39d6ULL, 0x696361ae3db1c721ULL},
546
+ /* 5^89 */ {0xc913936dd571c84cULL, 0x03bc3a19cd1e38e9ULL},
547
+ /* 5^90 */ {0xfb5878494ace3a5fULL, 0x04ab48a04065c723ULL},
548
+ /* 5^91 */ {0x9d174b2dcec0e47bULL, 0x62eb0d64283f9c76ULL},
549
+ /* 5^92 */ {0xc45d1df942711d9aULL, 0x3ba5d0bd324f8394ULL},
550
+ /* 5^93 */ {0xf5746577930d6500ULL, 0xca8f44ec7ee36479ULL},
551
+ /* 5^94 */ {0x9968bf6abbe85f20ULL, 0x7e998b13cf4e1ecbULL},
552
+ /* 5^95 */ {0xbfc2ef456ae276e8ULL, 0x9e3fedd8c321a67eULL},
553
+ /* 5^96 */ {0xefb3ab16c59b14a2ULL, 0xc5cfe94ef3ea101eULL},
554
+ /* 5^97 */ {0x95d04aee3b80ece5ULL, 0xbba1f1d158724a12ULL},
555
+ /* 5^98 */ {0xbb445da9ca61281fULL, 0x2a8a6e45ae8edc97ULL},
556
+ /* 5^99 */ {0xea1575143cf97226ULL, 0xf52d09d71a3293bdULL},
557
+ /* 5^100 */ {0x924d692ca61be758ULL, 0x593c2626705f9c56ULL},
558
+ /* 5^101 */ {0xb6e0c377cfa2e12eULL, 0x6f8b2fb00c77836cULL},
559
+ /* 5^102 */ {0xe498f455c38b997aULL, 0x0b6dfb9c0f956447ULL},
560
+ /* 5^103 */ {0x8edf98b59a373fecULL, 0x4724bd4189bd5eacULL},
561
+ /* 5^104 */ {0xb2977ee300c50fe7ULL, 0x58edec91ec2cb657ULL},
562
+ /* 5^105 */ {0xdf3d5e9bc0f653e1ULL, 0x2f2967b66737e3edULL},
563
+ /* 5^106 */ {0x8b865b215899f46cULL, 0xbd79e0d20082ee74ULL},
564
+ /* 5^107 */ {0xae67f1e9aec07187ULL, 0xecd8590680a3aa11ULL},
565
+ /* 5^108 */ {0xda01ee641a708de9ULL, 0xe80e6f4820cc9495ULL},
566
+ /* 5^109 */ {0x884134fe908658b2ULL, 0x3109058d147fdcddULL},
567
+ /* 5^110 */ {0xaa51823e34a7eedeULL, 0xbd4b46f0599fd415ULL},
568
+ /* 5^111 */ {0xd4e5e2cdc1d1ea96ULL, 0x6c9e18ac7007c91aULL},
569
+ /* 5^112 */ {0x850fadc09923329eULL, 0x03e2cf6bc604ddb0ULL},
570
+ /* 5^113 */ {0xa6539930bf6bff45ULL, 0x84db8346b786151cULL},
571
+ /* 5^114 */ {0xcfe87f7cef46ff16ULL, 0xe612641865679a63ULL},
572
+ /* 5^115 */ {0x81f14fae158c5f6eULL, 0x4fcb7e8f3f60c07eULL},
573
+ /* 5^116 */ {0xa26da3999aef7749ULL, 0xe3be5e330f38f09dULL},
574
+ /* 5^117 */ {0xcb090c8001ab551cULL, 0x5cadf5bfd3072cc5ULL},
575
+ /* 5^118 */ {0xfdcb4fa002162a63ULL, 0x73d9732fc7c8f7f6ULL},
576
+ /* 5^119 */ {0x9e9f11c4014dda7eULL, 0x2867e7fddcdd9afaULL},
577
+ /* 5^120 */ {0xc646d63501a1511dULL, 0xb281e1fd541501b8ULL},
578
+ /* 5^121 */ {0xf7d88bc24209a565ULL, 0x1f225a7ca91a4226ULL},
579
+ /* 5^122 */ {0x9ae757596946075fULL, 0x3375788de9b06958ULL},
580
+ /* 5^123 */ {0xc1a12d2fc3978937ULL, 0x0052d6b1641c83aeULL},
581
+ /* 5^124 */ {0xf209787bb47d6b84ULL, 0xc0678c5dbd23a49aULL},
582
+ /* 5^125 */ {0x9745eb4d50ce6332ULL, 0xf840b7ba963646e0ULL},
583
+ /* 5^126 */ {0xbd176620a501fbffULL, 0xb650e5a93bc3d898ULL},
584
+ /* 5^127 */ {0xec5d3fa8ce427affULL, 0xa3e51f138ab4cebeULL},
585
+ /* 5^128 */ {0x93ba47c980e98cdfULL, 0xc66f336c36b10137ULL},
586
+ /* 5^129 */ {0xb8a8d9bbe123f017ULL, 0xb80b0047445d4184ULL},
587
+ /* 5^130 */ {0xe6d3102ad96cec1dULL, 0xa60dc059157491e5ULL},
588
+ /* 5^131 */ {0x9043ea1ac7e41392ULL, 0x87c89837ad68db2fULL},
589
+ /* 5^132 */ {0xb454e4a179dd1877ULL, 0x29babe4598c311fbULL},
590
+ /* 5^133 */ {0xe16a1dc9d8545e94ULL, 0xf4296dd6fef3d67aULL},
591
+ /* 5^134 */ {0x8ce2529e2734bb1dULL, 0x1899e4a65f58660cULL},
592
+ /* 5^135 */ {0xb01ae745b101e9e4ULL, 0x5ec05dcff72e7f8fULL},
593
+ /* 5^136 */ {0xdc21a1171d42645dULL, 0x76707543f4fa1f73ULL},
594
+ /* 5^137 */ {0x899504ae72497ebaULL, 0x6a06494a791c53a8ULL},
595
+ /* 5^138 */ {0xabfa45da0edbde69ULL, 0x0487db9d17636892ULL},
596
+ /* 5^139 */ {0xd6f8d7509292d603ULL, 0x45a9d2845d3c42b6ULL},
597
+ /* 5^140 */ {0x865b86925b9bc5c2ULL, 0x0b8a2392ba45a9b2ULL},
598
+ /* 5^141 */ {0xa7f26836f282b732ULL, 0x8e6cac7768d7141eULL},
599
+ /* 5^142 */ {0xd1ef0244af2364ffULL, 0x3207d795430cd926ULL},
600
+ /* 5^143 */ {0x8335616aed761f1fULL, 0x7f44e6bd49e807b8ULL},
601
+ /* 5^144 */ {0xa402b9c5a8d3a6e7ULL, 0x5f16206c9c6209a6ULL},
602
+ /* 5^145 */ {0xcd036837130890a1ULL, 0x36dba887c37a8c0fULL},
603
+ /* 5^146 */ {0x802221226be55a64ULL, 0xc2494954da2c9789ULL},
604
+ /* 5^147 */ {0xa02aa96b06deb0fdULL, 0xf2db9baa10b7bd6cULL},
605
+ /* 5^148 */ {0xc83553c5c8965d3dULL, 0x6f92829494e5acc7ULL},
606
+ /* 5^149 */ {0xfa42a8b73abbf48cULL, 0xcb772339ba1f17f9ULL},
607
+ /* 5^150 */ {0x9c69a97284b578d7ULL, 0xff2a760414536efbULL},
608
+ /* 5^151 */ {0xc38413cf25e2d70dULL, 0xfef5138519684abaULL},
609
+ /* 5^152 */ {0xf46518c2ef5b8cd1ULL, 0x7eb258665fc25d69ULL},
610
+ /* 5^153 */ {0x98bf2f79d5993802ULL, 0xef2f773ffbd97a61ULL},
611
+ /* 5^154 */ {0xbeeefb584aff8603ULL, 0xaafb550ffacfd8faULL},
612
+ /* 5^155 */ {0xeeaaba2e5dbf6784ULL, 0x95ba2a53f983cf38ULL},
613
+ /* 5^156 */ {0x952ab45cfa97a0b2ULL, 0xdd945a747bf26183ULL},
614
+ /* 5^157 */ {0xba756174393d88dfULL, 0x94f971119aeef9e4ULL},
615
+ /* 5^158 */ {0xe912b9d1478ceb17ULL, 0x7a37cd5601aab85dULL},
616
+ /* 5^159 */ {0x91abb422ccb812eeULL, 0xac62e055c10ab33aULL},
617
+ /* 5^160 */ {0xb616a12b7fe617aaULL, 0x577b986b314d6009ULL},
618
+ /* 5^161 */ {0xe39c49765fdf9d94ULL, 0xed5a7e85fda0b80bULL},
619
+ /* 5^162 */ {0x8e41ade9fbebc27dULL, 0x14588f13be847307ULL},
620
+ /* 5^163 */ {0xb1d219647ae6b31cULL, 0x596eb2d8ae258fc8ULL},
621
+ /* 5^164 */ {0xde469fbd99a05fe3ULL, 0x6fca5f8ed9aef3bbULL},
622
+ /* 5^165 */ {0x8aec23d680043beeULL, 0x25de7bb9480d5854ULL},
623
+ /* 5^166 */ {0xada72ccc20054ae9ULL, 0xaf561aa79a10ae6aULL},
624
+ /* 5^167 */ {0xd910f7ff28069da4ULL, 0x1b2ba1518094da04ULL},
625
+ /* 5^168 */ {0x87aa9aff79042286ULL, 0x90fb44d2f05d0842ULL},
626
+ /* 5^169 */ {0xa99541bf57452b28ULL, 0x353a1607ac744a53ULL},
627
+ /* 5^170 */ {0xd3fa922f2d1675f2ULL, 0x42889b8997915ce8ULL},
628
+ /* 5^171 */ {0x847c9b5d7c2e09b7ULL, 0x69956135febada11ULL},
629
+ /* 5^172 */ {0xa59bc234db398c25ULL, 0x43fab9837e699095ULL},
630
+ /* 5^173 */ {0xcf02b2c21207ef2eULL, 0x94f967e45e03f4bbULL},
631
+ /* 5^174 */ {0x8161afb94b44f57dULL, 0x1d1be0eebac278f5ULL},
632
+ /* 5^175 */ {0xa1ba1ba79e1632dcULL, 0x6462d92a69731732ULL},
633
+ /* 5^176 */ {0xca28a291859bbf93ULL, 0x7d7b8f7503cfdcfeULL},
634
+ /* 5^177 */ {0xfcb2cb35e702af78ULL, 0x5cda735244c3d43eULL},
635
+ /* 5^178 */ {0x9defbf01b061adabULL, 0x3a0888136afa64a7ULL},
636
+ /* 5^179 */ {0xc56baec21c7a1916ULL, 0x088aaa1845b8fdd0ULL},
637
+ /* 5^180 */ {0xf6c69a72a3989f5bULL, 0x8aad549e57273d45ULL},
638
+ /* 5^181 */ {0x9a3c2087a63f6399ULL, 0x36ac54e2f678864bULL},
639
+ /* 5^182 */ {0xc0cb28a98fcf3c7fULL, 0x84576a1bb416a7ddULL},
640
+ /* 5^183 */ {0xf0fdf2d3f3c30b9fULL, 0x656d44a2a11c51d5ULL},
641
+ /* 5^184 */ {0x969eb7c47859e743ULL, 0x9f644ae5a4b1b325ULL},
642
+ /* 5^185 */ {0xbc4665b596706114ULL, 0x873d5d9f0dde1feeULL},
643
+ /* 5^186 */ {0xeb57ff22fc0c7959ULL, 0xa90cb506d155a7eaULL},
644
+ /* 5^187 */ {0x9316ff75dd87cbd8ULL, 0x09a7f12442d588f2ULL},
645
+ /* 5^188 */ {0xb7dcbf5354e9beceULL, 0x0c11ed6d538aeb2fULL},
646
+ /* 5^189 */ {0xe5d3ef282a242e81ULL, 0x8f1668c8a86da5faULL},
647
+ /* 5^190 */ {0x8fa475791a569d10ULL, 0xf96e017d694487bcULL},
648
+ /* 5^191 */ {0xb38d92d760ec4455ULL, 0x37c981dcc395a9acULL},
649
+ /* 5^192 */ {0xe070f78d3927556aULL, 0x85bbe253f47b1417ULL},
650
+ /* 5^193 */ {0x8c469ab843b89562ULL, 0x93956d7478ccec8eULL},
651
+ /* 5^194 */ {0xaf58416654a6babbULL, 0x387ac8d1970027b2ULL},
652
+ /* 5^195 */ {0xdb2e51bfe9d0696aULL, 0x06997b05fcc0319eULL},
653
+ /* 5^196 */ {0x88fcf317f22241e2ULL, 0x441fece3bdf81f03ULL},
654
+ /* 5^197 */ {0xab3c2fddeeaad25aULL, 0xd527e81cad7626c3ULL},
655
+ /* 5^198 */ {0xd60b3bd56a5586f1ULL, 0x8a71e223d8d3b074ULL},
656
+ /* 5^199 */ {0x85c7056562757456ULL, 0xf6872d5667844e49ULL},
657
+ /* 5^200 */ {0xa738c6bebb12d16cULL, 0xb428f8ac016561dbULL},
658
+ /* 5^201 */ {0xd106f86e69d785c7ULL, 0xe13336d701beba52ULL},
659
+ /* 5^202 */ {0x82a45b450226b39cULL, 0xecc0024661173473ULL},
660
+ /* 5^203 */ {0xa34d721642b06084ULL, 0x27f002d7f95d0190ULL},
661
+ /* 5^204 */ {0xcc20ce9bd35c78a5ULL, 0x31ec038df7b441f4ULL},
662
+ /* 5^205 */ {0xff290242c83396ceULL, 0x7e67047175a15271ULL},
663
+ /* 5^206 */ {0x9f79a169bd203e41ULL, 0x0f0062c6e984d386ULL},
664
+ /* 5^207 */ {0xc75809c42c684dd1ULL, 0x52c07b78a3e60868ULL},
665
+ /* 5^208 */ {0xf92e0c3537826145ULL, 0xa7709a56ccdf8a82ULL},
666
+ /* 5^209 */ {0x9bbcc7a142b17ccbULL, 0x88a66076400bb691ULL},
667
+ /* 5^210 */ {0xc2abf989935ddbfeULL, 0x6acff893d00ea435ULL},
668
+ /* 5^211 */ {0xf356f7ebf83552feULL, 0x0583f6b8c4124d43ULL},
669
+ /* 5^212 */ {0x98165af37b2153deULL, 0xc3727a337a8b704aULL},
670
+ /* 5^213 */ {0xbe1bf1b059e9a8d6ULL, 0x744f18c0592e4c5cULL},
671
+ /* 5^214 */ {0xeda2ee1c7064130cULL, 0x1162def06f79df73ULL},
672
+ /* 5^215 */ {0x9485d4d1c63e8be7ULL, 0x8addcb5645ac2ba8ULL},
673
+ /* 5^216 */ {0xb9a74a0637ce2ee1ULL, 0x6d953e2bd7173692ULL},
674
+ /* 5^217 */ {0xe8111c87c5c1ba99ULL, 0xc8fa8db6ccdd0437ULL},
675
+ /* 5^218 */ {0x910ab1d4db9914a0ULL, 0x1d9c9892400a22a2ULL},
676
+ /* 5^219 */ {0xb54d5e4a127f59c8ULL, 0x2503beb6d00cab4bULL},
677
+ /* 5^220 */ {0xe2a0b5dc971f303aULL, 0x2e44ae64840fd61dULL},
678
+ /* 5^221 */ {0x8da471a9de737e24ULL, 0x5ceaecfed289e5d2ULL},
679
+ /* 5^222 */ {0xb10d8e1456105dadULL, 0x7425a83e872c5f47ULL},
680
+ /* 5^223 */ {0xdd50f1996b947518ULL, 0xd12f124e28f77719ULL},
681
+ /* 5^224 */ {0x8a5296ffe33cc92fULL, 0x82bd6b70d99aaa6fULL},
682
+ /* 5^225 */ {0xace73cbfdc0bfb7bULL, 0x636cc64d1001550bULL},
683
+ /* 5^226 */ {0xd8210befd30efa5aULL, 0x3c47f7e05401aa4eULL},
684
+ /* 5^227 */ {0x8714a775e3e95c78ULL, 0x65acfaec34810a71ULL},
685
+ /* 5^228 */ {0xa8d9d1535ce3b396ULL, 0x7f1839a741a14d0dULL},
686
+ /* 5^229 */ {0xd31045a8341ca07cULL, 0x1ede48111209a050ULL},
687
+ /* 5^230 */ {0x83ea2b892091e44dULL, 0x934aed0aab460432ULL},
688
+ /* 5^231 */ {0xa4e4b66b68b65d60ULL, 0xf81da84d5617853fULL},
689
+ /* 5^232 */ {0xce1de40642e3f4b9ULL, 0x36251260ab9d668eULL},
690
+ /* 5^233 */ {0x80d2ae83e9ce78f3ULL, 0xc1d72b7c6b426019ULL},
691
+ /* 5^234 */ {0xa1075a24e4421730ULL, 0xb24cf65b8612f81fULL},
692
+ /* 5^235 */ {0xc94930ae1d529cfcULL, 0xdee033f26797b627ULL},
693
+ /* 5^236 */ {0xfb9b7cd9a4a7443cULL, 0x169840ef017da3b1ULL},
694
+ /* 5^237 */ {0x9d412e0806e88aa5ULL, 0x8e1f289560ee864eULL},
695
+ /* 5^238 */ {0xc491798a08a2ad4eULL, 0xf1a6f2bab92a27e2ULL},
696
+ /* 5^239 */ {0xf5b5d7ec8acb58a2ULL, 0xae10af696774b1dbULL},
697
+ /* 5^240 */ {0x9991a6f3d6bf1765ULL, 0xacca6da1e0a8ef29ULL},
698
+ /* 5^241 */ {0xbff610b0cc6edd3fULL, 0x17fd090a58d32af3ULL},
699
+ /* 5^242 */ {0xeff394dcff8a948eULL, 0xddfc4b4cef07f5b0ULL},
700
+ /* 5^243 */ {0x95f83d0a1fb69cd9ULL, 0x4abdaf101564f98eULL},
701
+ /* 5^244 */ {0xbb764c4ca7a4440fULL, 0x9d6d1ad41abe37f1ULL},
702
+ /* 5^245 */ {0xea53df5fd18d5513ULL, 0x84c86189216dc5edULL},
703
+ /* 5^246 */ {0x92746b9be2f8552cULL, 0x32fd3cf5b4e49bb4ULL},
704
+ /* 5^247 */ {0xb7118682dbb66a77ULL, 0x3fbc8c33221dc2a1ULL},
705
+ /* 5^248 */ {0xe4d5e82392a40515ULL, 0x0fabaf3feaa5334aULL},
706
+ /* 5^249 */ {0x8f05b1163ba6832dULL, 0x29cb4d87f2a7400eULL},
707
+ /* 5^250 */ {0xb2c71d5bca9023f8ULL, 0x743e20e9ef511012ULL},
708
+ /* 5^251 */ {0xdf78e4b2bd342cf6ULL, 0x914da9246b255416ULL},
709
+ /* 5^252 */ {0x8bab8eefb6409c1aULL, 0x1ad089b6c2f7548eULL},
710
+ /* 5^253 */ {0xae9672aba3d0c320ULL, 0xa184ac2473b529b1ULL},
711
+ /* 5^254 */ {0xda3c0f568cc4f3e8ULL, 0xc9e5d72d90a2741eULL},
712
+ /* 5^255 */ {0x8865899617fb1871ULL, 0x7e2fa67c7a658892ULL},
713
+ /* 5^256 */ {0xaa7eebfb9df9de8dULL, 0xddbb901b98feeab7ULL},
714
+ /* 5^257 */ {0xd51ea6fa85785631ULL, 0x552a74227f3ea565ULL},
715
+ /* 5^258 */ {0x8533285c936b35deULL, 0xd53a88958f87275fULL},
716
+ /* 5^259 */ {0xa67ff273b8460356ULL, 0x8a892abaf368f137ULL},
717
+ /* 5^260 */ {0xd01fef10a657842cULL, 0x2d2b7569b0432d85ULL},
718
+ /* 5^261 */ {0x8213f56a67f6b29bULL, 0x9c3b29620e29fc73ULL},
719
+ /* 5^262 */ {0xa298f2c501f45f42ULL, 0x8349f3ba91b47b8fULL},
720
+ /* 5^263 */ {0xcb3f2f7642717713ULL, 0x241c70a936219a73ULL},
721
+ /* 5^264 */ {0xfe0efb53d30dd4d7ULL, 0xed238cd383aa0110ULL},
722
+ /* 5^265 */ {0x9ec95d1463e8a506ULL, 0xf4363804324a40aaULL},
723
+ /* 5^266 */ {0xc67bb4597ce2ce48ULL, 0xb143c6053edcd0d5ULL},
724
+ /* 5^267 */ {0xf81aa16fdc1b81daULL, 0xdd94b7868e94050aULL},
725
+ /* 5^268 */ {0x9b10a4e5e9913128ULL, 0xca7cf2b4191c8326ULL},
726
+ /* 5^269 */ {0xc1d4ce1f63f57d72ULL, 0xfd1c2f611f63a3f0ULL},
727
+ /* 5^270 */ {0xf24a01a73cf2dccfULL, 0xbc633b39673c8cecULL},
728
+ /* 5^271 */ {0x976e41088617ca01ULL, 0xd5be0503e085d813ULL},
729
+ /* 5^272 */ {0xbd49d14aa79dbc82ULL, 0x4b2d8644d8a74e18ULL},
730
+ /* 5^273 */ {0xec9c459d51852ba2ULL, 0xddf8e7d60ed1219eULL},
731
+ /* 5^274 */ {0x93e1ab8252f33b45ULL, 0xcabb90e5c942b503ULL},
732
+ /* 5^275 */ {0xb8da1662e7b00a17ULL, 0x3d6a751f3b936243ULL},
733
+ /* 5^276 */ {0xe7109bfba19c0c9dULL, 0x0cc512670a783ad4ULL},
734
+ /* 5^277 */ {0x906a617d450187e2ULL, 0x27fb2b80668b24c5ULL},
735
+ /* 5^278 */ {0xb484f9dc9641e9daULL, 0xb1f9f660802dedf6ULL},
736
+ /* 5^279 */ {0xe1a63853bbd26451ULL, 0x5e7873f8a0396973ULL},
737
+ /* 5^280 */ {0x8d07e33455637eb2ULL, 0xdb0b487b6423e1e8ULL},
738
+ /* 5^281 */ {0xb049dc016abc5e5fULL, 0x91ce1a9a3d2cda62ULL},
739
+ /* 5^282 */ {0xdc5c5301c56b75f7ULL, 0x7641a140cc7810fbULL},
740
+ /* 5^283 */ {0x89b9b3e11b6329baULL, 0xa9e904c87fcb0a9dULL},
741
+ /* 5^284 */ {0xac2820d9623bf429ULL, 0x546345fa9fbdcd44ULL},
742
+ /* 5^285 */ {0xd732290fbacaf133ULL, 0xa97c177947ad4095ULL},
743
+ /* 5^286 */ {0x867f59a9d4bed6c0ULL, 0x49ed8eabcccc485dULL},
744
+ /* 5^287 */ {0xa81f301449ee8c70ULL, 0x5c68f256bfff5a74ULL},
745
+ /* 5^288 */ {0xd226fc195c6a2f8cULL, 0x73832eec6fff3111ULL},
746
+ /* 5^289 */ {0x83585d8fd9c25db7ULL, 0xc831fd53c5ff7eabULL},
747
+ /* 5^290 */ {0xa42e74f3d032f525ULL, 0xba3e7ca8b77f5e55ULL},
748
+ /* 5^291 */ {0xcd3a1230c43fb26fULL, 0x28ce1bd2e55f35ebULL},
749
+ /* 5^292 */ {0x80444b5e7aa7cf85ULL, 0x7980d163cf5b81b3ULL},
750
+ /* 5^293 */ {0xa0555e361951c366ULL, 0xd7e105bcc332621fULL},
751
+ /* 5^294 */ {0xc86ab5c39fa63440ULL, 0x8dd9472bf3fefaa7ULL},
752
+ /* 5^295 */ {0xfa856334878fc150ULL, 0xb14f98f6f0feb951ULL},
753
+ /* 5^296 */ {0x9c935e00d4b9d8d2ULL, 0x6ed1bf9a569f33d3ULL},
754
+ /* 5^297 */ {0xc3b8358109e84f07ULL, 0x0a862f80ec4700c8ULL},
755
+ /* 5^298 */ {0xf4a642e14c6262c8ULL, 0xcd27bb612758c0faULL},
756
+ /* 5^299 */ {0x98e7e9cccfbd7dbdULL, 0x8038d51cb897789cULL},
757
+ /* 5^300 */ {0xbf21e44003acdd2cULL, 0xe0470a63e6bd56c3ULL},
758
+ /* 5^301 */ {0xeeea5d5004981478ULL, 0x1858ccfce06cac74ULL},
759
+ /* 5^302 */ {0x95527a5202df0ccbULL, 0x0f37801e0c43ebc8ULL},
760
+ /* 5^303 */ {0xbaa718e68396cffdULL, 0xd30560258f54e6baULL},
761
+ /* 5^304 */ {0xe950df20247c83fdULL, 0x47c6b82ef32a2069ULL},
762
+ /* 5^305 */ {0x91d28b7416cdd27eULL, 0x4cdc331d57fa5441ULL},
763
+ /* 5^306 */ {0xb6472e511c81471dULL, 0xe0133fe4adf8e952ULL},
764
+ /* 5^307 */ {0xe3d8f9e563a198e5ULL, 0x58180fddd97723a6ULL},
765
+ /* 5^308 */ {0x8e679c2f5e44ff8fULL, 0x570f09eaa7ea7648ULL},
766
+ };
767
+
768
+ /* ============================================================================
769
+ * Eisel-Lemire algorithm core
770
+ * ============================================================================ */
771
+
772
+ /*
773
+ * Core Eisel-Lemire conversion routine.
774
+ *
775
+ * Takes a decimal mantissa and exponent, returns the IEEE 754 double.
776
+ * Returns false if the algorithm can't determine the correct result
777
+ * (ambiguous rounding case), in which case the caller should fall back
778
+ * to a slower but always-correct method.
779
+ */
780
+ static bool
781
+ eisel_lemire64(uint64_t mantissa, int exp10, bool negative, double *result)
782
+ {
783
+ /* Handle zero */
784
+ if (mantissa == 0) {
785
+ *result = negative ? -0.0 : 0.0;
786
+ return true;
787
+ }
788
+
789
+ /* Check exponent bounds */
790
+ if (exp10 < FASTFLOAT_SMALLEST_POWER || exp10 > FASTFLOAT_LARGEST_POWER) {
791
+ return false;
792
+ }
793
+
794
+ /* Normalize the mantissa (shift left until MSB is set) */
795
+ int lz = clz64(mantissa);
796
+ mantissa <<= lz;
797
+
798
+ /* Get the power of 5 from the lookup table */
799
+ int table_idx = exp10 - FASTFLOAT_SMALLEST_POWER;
800
+ uint64_t pow5_hi = POWERS_OF_FIVE_128[table_idx][0];
801
+ uint64_t pow5_lo = POWERS_OF_FIVE_128[table_idx][1];
802
+
803
+ /* Compute mantissa * 5^exp10 using 128-bit multiplication */
804
+ uint64_t hi1, lo1, hi2, lo2;
805
+ mul128(mantissa, pow5_lo, &hi1, &lo1);
806
+ mul128(mantissa, pow5_hi, &hi2, &lo2);
807
+
808
+ uint64_t sum = hi1 + lo2;
809
+ uint64_t high = hi2 + (sum < hi1 ? 1 : 0);
810
+
811
+ /*
812
+ * Check for ambiguous rounding.
813
+ * If the lower bits are exactly at the midpoint, we can't determine
814
+ * the correct rounding without more precision.
815
+ */
816
+ if ((sum == 0) && ((high & 0x1FF) == 0x1FF) &&
817
+ (lo1 + mantissa < lo1)) {
818
+ return false;
819
+ }
820
+
821
+ /* Compute the binary exponent */
822
+ int exp2 = (int)(((152170 + 65536) * exp10) >> 16) + 1024 + 63 - lz;
823
+
824
+ /* Normalize: ensure high bit is in position 63 */
825
+ if ((high >> 63) == 0) {
826
+ high = (high << 1) | (sum >> 63);
827
+ exp2--;
828
+ }
829
+
830
+ /* Round to 53 bits */
831
+ uint64_t mantissa_out = high >> 11;
832
+ uint64_t round_bit = (high >> 10) & 1;
833
+ uint64_t sticky = (high & 0x3FF) | sum | lo1;
834
+
835
+ /* Round to nearest, ties to even */
836
+ if (round_bit && (sticky || (mantissa_out & 1))) {
837
+ mantissa_out++;
838
+ if (mantissa_out == (1ULL << 53)) {
839
+ mantissa_out = 1ULL << 52;
840
+ exp2++;
841
+ }
842
+ }
843
+
844
+ /* Check for overflow/underflow */
845
+ if (exp2 >= 2047) {
846
+ *result = negative ? -HUGE_VAL : HUGE_VAL;
847
+ return true;
848
+ }
849
+ if (exp2 <= 0) {
850
+ /* Subnormal or zero */
851
+ if (exp2 < -52) {
852
+ *result = negative ? -0.0 : 0.0;
853
+ return true;
854
+ }
855
+ mantissa_out >>= (1 - exp2);
856
+ exp2 = 0;
857
+ } else {
858
+ /* Normal number: remove implicit bit */
859
+ mantissa_out &= ~(1ULL << 52);
860
+ }
861
+
862
+ /* Assemble the IEEE 754 double */
863
+ uint64_t bits = mantissa_out | ((uint64_t)exp2 << 52);
864
+ if (negative) {
865
+ bits |= (1ULL << 63);
866
+ }
867
+
868
+ union { uint64_t u; double d; } u;
869
+ u.u = bits;
870
+ *result = u.d;
871
+ return true;
872
+ }
873
+
874
+ /* ============================================================================
875
+ * String parsing
876
+ * ============================================================================ */
877
+
878
+ static inline bool
879
+ is_digit(char c)
880
+ {
881
+ return c >= '0' && c <= '9';
882
+ }
883
+
884
+ static inline bool
885
+ is_space(char c)
886
+ {
887
+ return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v';
888
+ }
889
+
890
+ /*
891
+ * Parse a decimal floating point number from string.
892
+ */
893
+ static const char *
894
+ parse_decimal(const char *p, const char *end, uint64_t *mantissa, int *exp10,
895
+ bool *negative, bool *valid, bool *too_many_digits)
896
+ {
897
+ uint64_t mant = 0;
898
+ int exp = 0;
899
+ int digits_after_dot = 0;
900
+ bool has_dot = false;
901
+ bool has_digits = false;
902
+ int digit_count = 0;
903
+
904
+ *valid = false;
905
+ *negative = false;
906
+ *too_many_digits = false;
907
+
908
+ /* Skip leading whitespace */
909
+ while (p < end && is_space(*p)) p++;
910
+
911
+ /* Parse sign */
912
+ if (p < end && *p == '-') {
913
+ *negative = true;
914
+ p++;
915
+ } else if (p < end && *p == '+') {
916
+ p++;
917
+ }
918
+
919
+ /* Parse digits and decimal point */
920
+ while (p < end) {
921
+ char c = *p;
922
+ if (is_digit(c)) {
923
+ has_digits = true;
924
+ if (mant != 0 || c != '0') {
925
+ digit_count++;
926
+ }
927
+ if (digit_count <= 19) {
928
+ mant = mant * 10 + (c - '0');
929
+ if (has_dot) digits_after_dot++;
930
+ } else {
931
+ *too_many_digits = true;
932
+ if (!has_dot) exp++;
933
+ }
934
+ p++;
935
+ } else if (c == '.' && !has_dot) {
936
+ has_dot = true;
937
+ p++;
938
+ } else if (c == '_' && has_digits) {
939
+ /* Ruby allows underscores in numbers */
940
+ p++;
941
+ } else {
942
+ break;
943
+ }
944
+ }
945
+
946
+ if (!has_digits) {
947
+ return p;
948
+ }
949
+
950
+ exp -= digits_after_dot;
951
+
952
+ /* Parse exponent */
953
+ if (p < end && (*p == 'e' || *p == 'E')) {
954
+ p++;
955
+ bool exp_negative = false;
956
+ int exp_value = 0;
957
+
958
+ if (p < end && *p == '-') {
959
+ exp_negative = true;
960
+ p++;
961
+ } else if (p < end && *p == '+') {
962
+ p++;
963
+ }
964
+
965
+ bool has_exp_digits = false;
966
+ while (p < end && is_digit(*p)) {
967
+ has_exp_digits = true;
968
+ if (exp_value < 10000) {
969
+ exp_value = exp_value * 10 + (*p - '0');
970
+ }
971
+ p++;
972
+ }
973
+
974
+ if (!has_exp_digits) {
975
+ return p;
976
+ }
977
+
978
+ exp += exp_negative ? -exp_value : exp_value;
979
+ }
980
+
981
+ *mantissa = mant;
982
+ *exp10 = exp;
983
+ *valid = true;
984
+ return p;
985
+ }
986
+
987
+ /*
988
+ * Main parsing function using Eisel-Lemire algorithm.
989
+ * Falls back to Ruby's strtod for edge cases.
990
+ */
991
+ static double
992
+ fast_float_parse(const char *str)
993
+ {
994
+ const char *p = str;
995
+ const char *end = str + strlen(str);
996
+ uint64_t mantissa;
997
+ int exp10;
998
+ bool negative;
999
+ bool valid;
1000
+ bool too_many_digits;
1001
+ double result;
1002
+
1003
+ /* Skip leading whitespace */
1004
+ while (p < end && is_space(*p)) p++;
1005
+
1006
+ /* Handle special values */
1007
+ if (p < end) {
1008
+ if ((p[0] == 'i' || p[0] == 'I') && (end - p >= 3)) {
1009
+ if ((p[1] == 'n' || p[1] == 'N') && (p[2] == 'f' || p[2] == 'F')) {
1010
+ return INFINITY;
1011
+ }
1012
+ }
1013
+ if ((p[0] == 'n' || p[0] == 'N') && (end - p >= 3)) {
1014
+ if ((p[1] == 'a' || p[1] == 'A') && (p[2] == 'n' || p[2] == 'N')) {
1015
+ return NAN;
1016
+ }
1017
+ }
1018
+ if ((p[0] == '+' || p[0] == '-') && (end - p >= 4)) {
1019
+ bool neg = (p[0] == '-');
1020
+ if ((p[1] == 'i' || p[1] == 'I') &&
1021
+ (p[2] == 'n' || p[2] == 'N') &&
1022
+ (p[3] == 'f' || p[3] == 'F')) {
1023
+ return neg ? -INFINITY : INFINITY;
1024
+ }
1025
+ }
1026
+ }
1027
+
1028
+ /* Check for hex floats - fall back to strtod */
1029
+ {
1030
+ const char *hp = p;
1031
+ if (*hp == '+' || *hp == '-') hp++;
1032
+ if (hp[0] == '0' && (hp[1] == 'x' || hp[1] == 'X')) {
1033
+ return strtod(str, NULL);
1034
+ }
1035
+ }
1036
+
1037
+ /* Parse decimal */
1038
+ parse_decimal(str, end, &mantissa, &exp10, &negative, &valid, &too_many_digits);
1039
+
1040
+ if (!valid || too_many_digits) {
1041
+ return strtod(str, NULL);
1042
+ }
1043
+
1044
+ /* Try Eisel-Lemire */
1045
+ if (eisel_lemire64(mantissa, exp10, negative, &result)) {
1046
+ return result;
1047
+ }
1048
+
1049
+ /* Fall back to strtod */
1050
+ return strtod(str, NULL);
1051
+ }
1052
+
1053
+ /* ============================================================================
1054
+ * Ruby bindings
1055
+ * ============================================================================ */
1056
+
1057
+ static VALUE rb_mFastFloatLemire;
1058
+
1059
+ /*
1060
+ * Parse a string to a Float using the Eisel-Lemire algorithm.
1061
+ *
1062
+ * @param str [String] The string to parse
1063
+ * @return [Float] The parsed floating-point number
1064
+ *
1065
+ * @example
1066
+ * FastFloatLemire.parse("3.141592653589793") #=> 3.141592653589793
1067
+ * FastFloatLemire.parse("1.5e10") #=> 15000000000.0
1068
+ */
1069
+ static VALUE
1070
+ rb_fast_float_parse(VALUE self, VALUE str)
1071
+ {
1072
+ Check_Type(str, T_STRING);
1073
+ const char *cstr = StringValueCStr(str);
1074
+ double result = fast_float_parse(cstr);
1075
+ return DBL2NUM(result);
1076
+ }
1077
+
1078
+ /*
1079
+ * Parse an array of strings to Floats.
1080
+ * More efficient than calling parse() repeatedly due to reduced method call overhead.
1081
+ *
1082
+ * @param array [Array<String>] The strings to parse
1083
+ * @return [Array<Float>] The parsed floating-point numbers
1084
+ */
1085
+ static VALUE
1086
+ rb_fast_float_parse_array(VALUE self, VALUE array)
1087
+ {
1088
+ Check_Type(array, T_ARRAY);
1089
+ long len = RARRAY_LEN(array);
1090
+ VALUE result = rb_ary_new2(len);
1091
+
1092
+ for (long i = 0; i < len; i++) {
1093
+ VALUE str = rb_ary_entry(array, i);
1094
+ Check_Type(str, T_STRING);
1095
+ const char *cstr = StringValueCStr(str);
1096
+ double d = fast_float_parse(cstr);
1097
+ rb_ary_push(result, DBL2NUM(d));
1098
+ }
1099
+
1100
+ return result;
1101
+ }
1102
+
1103
+ void
1104
+ Init_fast_float_lemire(void)
1105
+ {
1106
+ rb_mFastFloatLemire = rb_define_module("FastFloatLemire");
1107
+
1108
+ rb_define_singleton_method(rb_mFastFloatLemire, "parse", rb_fast_float_parse, 1);
1109
+ rb_define_singleton_method(rb_mFastFloatLemire, "parse_array", rb_fast_float_parse_array, 1);
1110
+ }
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FastFloatLemire
4
+ # Current gem version.
5
+ VERSION = '0.1.0'
6
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'fast_float_lemire/version'
4
+ require_relative 'fast_float_lemire/fast_float_lemire'
5
+
6
+ # Eisel-Lemire algorithm for fast string-to-float conversion.
7
+ #
8
+ # This gem provides an alternative float parsing implementation that is
9
+ # significantly faster for numbers with many significant digits (like Pi),
10
+ # but slightly slower for simple numbers (like "1.5").
11
+ #
12
+ # @note This is an EDUCATIONAL gem demonstrating why this algorithm was
13
+ # NOT submitted to Ruby core - it regresses performance on simple numbers
14
+ # which are the common case in typical Ruby applications.
15
+ #
16
+ # @example Basic usage
17
+ # FastFloatLemire.parse("3.141592653589793") #=> 3.141592653589793
18
+ #
19
+ # @example Bulk parsing
20
+ # FastFloatLemire.parse_array(["1.5", "3.14159", "2.71828"])
21
+ #
22
+ # @see https://arxiv.org/abs/2101.11408 Eisel-Lemire paper
23
+ module FastFloatLemire
24
+ # Base error class for FastFloatLemire exceptions.
25
+ class Error < StandardError; end
26
+
27
+ # Methods parse() and parse_array() are defined in the C extension
28
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fast_float_lemire
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Maciej Mensfeld
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: |
13
+ An educational Ruby C extension implementing the Eisel-Lemire algorithm
14
+ for string-to-float conversion. This gem demonstrates why this optimization,
15
+ despite being ~2.6x faster for complex numbers, was NOT submitted to Ruby core:
16
+ it regresses performance by ~9% on simple numbers (the common case).
17
+
18
+ Use this gem to learn about float parsing algorithms and their tradeoffs,
19
+ or if you specifically work with high-precision scientific data.
20
+ email:
21
+ - maciej@mensfeld.pl
22
+ executables: []
23
+ extensions:
24
+ - ext/fast_float_lemire/extconf.rb
25
+ extra_rdoc_files: []
26
+ files:
27
+ - LICENSE.txt
28
+ - README.md
29
+ - ext/fast_float_lemire/extconf.rb
30
+ - ext/fast_float_lemire/fast_float_lemire.c
31
+ - lib/fast_float_lemire.rb
32
+ - lib/fast_float_lemire/fast_float_lemire.so
33
+ - lib/fast_float_lemire/version.rb
34
+ homepage: https://github.com/mensfeld/fast_float_lemire
35
+ licenses:
36
+ - MIT
37
+ metadata:
38
+ homepage_uri: https://github.com/mensfeld/fast_float_lemire
39
+ source_code_uri: https://github.com/mensfeld/fast_float_lemire
40
+ documentation_uri: https://github.com/mensfeld/fast_float_lemire
41
+ rubygems_mfa_required: 'true'
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 3.0.0
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubygems_version: 4.0.0.beta2
57
+ specification_version: 4
58
+ summary: Eisel-Lemire algorithm for fast string-to-float conversion
59
+ test_files: []