/src/serenity/AK/FloatingPointStringConversions.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2022, David Tuin <davidot@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <AK/BigIntBase.h> |
8 | | #include <AK/CharacterTypes.h> |
9 | | #include <AK/FloatingPointStringConversions.h> |
10 | | #include <AK/Format.h> |
11 | | #include <AK/ScopeGuard.h> |
12 | | #include <AK/StringView.h> |
13 | | #include <AK/UFixedBigInt.h> |
14 | | #include <AK/UFixedBigIntDivision.h> |
15 | | |
16 | | namespace AK { |
17 | | |
18 | | // This entire algorithm is an implementation of the paper: Number Parsing at a Gigabyte per Second |
19 | | // by Daniel Lemire, available at https://arxiv.org/abs/2101.11408 and an implementation |
20 | | // at https://github.com/fastfloat/fast_float |
21 | | // There is also a perhaps more easily understandable explanation |
22 | | // at https://nigeltao.github.io/blog/2020/eisel-lemire.html |
23 | | |
24 | | template<typename T> |
25 | | concept ParseableFloatingPoint = IsFloatingPoint<T> && (sizeof(T) == sizeof(u32) || sizeof(T) == sizeof(u64)); |
26 | | |
27 | | template<ParseableFloatingPoint T> |
28 | | struct FloatingPointInfo { |
29 | | static_assert(sizeof(T) == sizeof(u64) || sizeof(T) == sizeof(u32)); |
30 | | using SameSizeUnsigned = Conditional<sizeof(T) == sizeof(u64), u64, u32>; |
31 | | |
32 | | // Implementing just this gives all the other bit sizes and mask immediately. |
33 | | static constexpr inline i32 mantissa_bits() |
34 | 1.68M | { |
35 | | if constexpr (sizeof(T) == sizeof(u64)) |
36 | 1.68M | return 52; |
37 | | |
38 | 0 | return 23; |
39 | 1.68M | } AK::FloatingPointInfo<double>::mantissa_bits() Line | Count | Source | 34 | 1.68M | { | 35 | | if constexpr (sizeof(T) == sizeof(u64)) | 36 | 1.68M | return 52; | 37 | | | 38 | 0 | return 23; | 39 | 1.68M | } |
Unexecuted instantiation: AK::FloatingPointInfo<float>::mantissa_bits() |
40 | | |
41 | | static constexpr inline i32 exponent_bits() |
42 | 436k | { |
43 | 436k | return sizeof(T) * 8u - 1u - mantissa_bits(); |
44 | 436k | } AK::FloatingPointInfo<double>::exponent_bits() Line | Count | Source | 42 | 436k | { | 43 | 436k | return sizeof(T) * 8u - 1u - mantissa_bits(); | 44 | 436k | } |
Unexecuted instantiation: AK::FloatingPointInfo<float>::exponent_bits() |
45 | | |
46 | | static constexpr inline i32 exponent_bias() |
47 | 213k | { |
48 | 213k | return (1 << (exponent_bits() - 1)) - 1; |
49 | 213k | } AK::FloatingPointInfo<double>::exponent_bias() Line | Count | Source | 47 | 213k | { | 48 | 213k | return (1 << (exponent_bits() - 1)) - 1; | 49 | 213k | } |
Unexecuted instantiation: AK::FloatingPointInfo<float>::exponent_bias() |
50 | | |
51 | | static constexpr inline i32 minimum_exponent() |
52 | | { |
53 | | return -exponent_bias(); |
54 | | } |
55 | | |
56 | | static constexpr inline i32 infinity_exponent() |
57 | 223k | { |
58 | 223k | static_assert(exponent_bits() < 31); |
59 | 223k | return (1 << exponent_bits()) - 1; |
60 | 223k | } AK::FloatingPointInfo<double>::infinity_exponent() Line | Count | Source | 57 | 223k | { | 58 | 223k | static_assert(exponent_bits() < 31); | 59 | 223k | return (1 << exponent_bits()) - 1; | 60 | 223k | } |
Unexecuted instantiation: AK::FloatingPointInfo<float>::infinity_exponent() |
61 | | |
62 | | static constexpr inline i32 sign_bit_index() |
63 | 186k | { |
64 | 186k | return sizeof(T) * 8 - 1; |
65 | 186k | } AK::FloatingPointInfo<double>::sign_bit_index() Line | Count | Source | 63 | 186k | { | 64 | 186k | return sizeof(T) * 8 - 1; | 65 | 186k | } |
Unexecuted instantiation: AK::FloatingPointInfo<float>::sign_bit_index() |
66 | | |
67 | | static constexpr inline SameSizeUnsigned sign_mask() |
68 | | { |
69 | | return SameSizeUnsigned { 1 } << sign_bit_index(); |
70 | | } |
71 | | |
72 | | static constexpr inline SameSizeUnsigned mantissa_mask() |
73 | 7.86k | { |
74 | 7.86k | return (SameSizeUnsigned { 1 } << mantissa_bits()) - 1; |
75 | 7.86k | } AK::FloatingPointInfo<double>::mantissa_mask() Line | Count | Source | 73 | 7.86k | { | 74 | 7.86k | return (SameSizeUnsigned { 1 } << mantissa_bits()) - 1; | 75 | 7.86k | } |
Unexecuted instantiation: AK::FloatingPointInfo<float>::mantissa_mask() |
76 | | |
77 | | static constexpr inline SameSizeUnsigned exponent_mask() |
78 | 14.9k | { |
79 | 14.9k | return SameSizeUnsigned { infinity_exponent() } << mantissa_bits(); |
80 | 14.9k | } AK::FloatingPointInfo<double>::exponent_mask() Line | Count | Source | 78 | 14.9k | { | 79 | 14.9k | return SameSizeUnsigned { infinity_exponent() } << mantissa_bits(); | 80 | 14.9k | } |
Unexecuted instantiation: AK::FloatingPointInfo<float>::exponent_mask() |
81 | | |
82 | | static constexpr inline i32 max_exponent_round_to_even() |
83 | 155k | { |
84 | | if constexpr (sizeof(T) == sizeof(u64)) |
85 | 155k | return 23; |
86 | | |
87 | 0 | return 10; |
88 | 155k | } AK::FloatingPointInfo<double>::max_exponent_round_to_even() Line | Count | Source | 83 | 155k | { | 84 | | if constexpr (sizeof(T) == sizeof(u64)) | 85 | 155k | return 23; | 86 | | | 87 | 0 | return 10; | 88 | 155k | } |
Unexecuted instantiation: AK::FloatingPointInfo<float>::max_exponent_round_to_even() |
89 | | |
90 | | static constexpr inline i32 min_exponent_round_to_even() |
91 | 156k | { |
92 | | if constexpr (sizeof(T) == sizeof(u64)) |
93 | 156k | return -4; |
94 | | |
95 | 0 | return -17; |
96 | 156k | } AK::FloatingPointInfo<double>::min_exponent_round_to_even() Line | Count | Source | 91 | 156k | { | 92 | | if constexpr (sizeof(T) == sizeof(u64)) | 93 | 156k | return -4; | 94 | | | 95 | 0 | return -17; | 96 | 156k | } |
Unexecuted instantiation: AK::FloatingPointInfo<float>::min_exponent_round_to_even() |
97 | | |
98 | | static constexpr inline size_t max_possible_digits_needed_for_parsing() |
99 | 0 | { |
100 | 0 | if constexpr (sizeof(T) == sizeof(u64)) |
101 | 0 | return 769; |
102 | 0 |
|
103 | 0 | return 114; |
104 | 0 | } Unexecuted instantiation: AK::FloatingPointInfo<double>::max_possible_digits_needed_for_parsing() Unexecuted instantiation: AK::FloatingPointInfo<float>::max_possible_digits_needed_for_parsing() |
105 | | |
106 | | static constexpr inline i32 max_power_of_10() |
107 | 193k | { |
108 | | if constexpr (sizeof(T) == sizeof(u64)) |
109 | 193k | return 308; |
110 | | |
111 | 0 | return 38; |
112 | 193k | } AK::FloatingPointInfo<double>::max_power_of_10() Line | Count | Source | 107 | 193k | { | 108 | | if constexpr (sizeof(T) == sizeof(u64)) | 109 | 193k | return 308; | 110 | | | 111 | 0 | return 38; | 112 | 193k | } |
Unexecuted instantiation: AK::FloatingPointInfo<float>::max_power_of_10() |
113 | | |
114 | | static constexpr inline i32 min_power_of_10() |
115 | 194k | { |
116 | | // Closest double value to zero is xe-324 and since we have at most 19 digits |
117 | | // we know that -324 -19 = -343 so exponent below that must be zero (for double) |
118 | | if constexpr (sizeof(T) == sizeof(u64)) |
119 | 194k | return -342; |
120 | | |
121 | 0 | return -65; |
122 | 194k | } AK::FloatingPointInfo<double>::min_power_of_10() Line | Count | Source | 115 | 194k | { | 116 | | // Closest double value to zero is xe-324 and since we have at most 19 digits | 117 | | // we know that -324 -19 = -343 so exponent below that must be zero (for double) | 118 | | if constexpr (sizeof(T) == sizeof(u64)) | 119 | 194k | return -342; | 120 | | | 121 | 0 | return -65; | 122 | 194k | } |
Unexecuted instantiation: AK::FloatingPointInfo<float>::min_power_of_10() |
123 | | |
124 | | static constexpr inline i32 max_exact_power_of_10() |
125 | 619k | { |
126 | | // These are the largest power of 10 representable in T |
127 | | // So all powers of 10*i less than or equal to this should be the exact |
128 | | // values, be careful as they can be above "safe integer" limits. |
129 | | |
130 | | if constexpr (sizeof(T) == sizeof(u64)) |
131 | 619k | return 22; |
132 | | |
133 | 0 | return 10; |
134 | 619k | } AK::FloatingPointInfo<double>::max_exact_power_of_10() Line | Count | Source | 125 | 619k | { | 126 | | // These are the largest power of 10 representable in T | 127 | | // So all powers of 10*i less than or equal to this should be the exact | 128 | | // values, be careful as they can be above "safe integer" limits. | 129 | | | 130 | | if constexpr (sizeof(T) == sizeof(u64)) | 131 | 619k | return 22; | 132 | | | 133 | 0 | return 10; | 134 | 619k | } |
Unexecuted instantiation: AK::FloatingPointInfo<float>::max_exact_power_of_10() |
135 | | |
136 | | static constexpr inline T power_of_ten(i32 exponent) |
137 | 98.3k | { |
138 | 98.3k | VERIFY(exponent <= max_exact_power_of_10()); |
139 | 98.3k | VERIFY(exponent >= 0); |
140 | 98.3k | return m_powers_of_ten_stored[exponent]; |
141 | 98.3k | } AK::FloatingPointInfo<double>::power_of_ten(int) Line | Count | Source | 137 | 98.3k | { | 138 | 98.3k | VERIFY(exponent <= max_exact_power_of_10()); | 139 | 98.3k | VERIFY(exponent >= 0); | 140 | 98.3k | return m_powers_of_ten_stored[exponent]; | 141 | 98.3k | } |
Unexecuted instantiation: AK::FloatingPointInfo<float>::power_of_ten(int) |
142 | | |
143 | | template<u32 MaxPower> |
144 | | static constexpr inline Array<T, MaxPower + 1> compute_powers_of_ten() |
145 | 0 | { |
146 | 0 | // All these values are guaranteed to be exact all powers of MaxPower is the |
147 | 0 | Array<T, MaxPower + 1> values {}; |
148 | 0 |
|
149 | 0 | values[0] = T(1.0); |
150 | 0 | T ten = T(10.); |
151 | 0 |
|
152 | 0 | for (u32 i = 1; i <= MaxPower; ++i) |
153 | 0 | values[i] = values[i - 1] * ten; |
154 | 0 |
|
155 | 0 | return values; |
156 | 0 | } Unexecuted instantiation: AK::Array<double, (22u)+(1)> AK::FloatingPointInfo<double>::compute_powers_of_ten<22u>() Unexecuted instantiation: AK::Array<float, (10u)+(1)> AK::FloatingPointInfo<float>::compute_powers_of_ten<10u>() |
157 | | |
158 | | static constexpr auto m_powers_of_ten_stored = compute_powers_of_ten<max_exact_power_of_10()>(); |
159 | | }; |
160 | | |
161 | | template<typename T> |
162 | | using BitSizedUnsignedForFloatingPoint = typename FloatingPointInfo<T>::SameSizeUnsigned; |
163 | | |
164 | | struct BasicParseResult { |
165 | | u64 mantissa = 0; |
166 | | i64 exponent = 0; |
167 | | bool valid = false; |
168 | | bool negative = false; |
169 | | bool more_than_19_digits_with_overflow = false; |
170 | | char const* last_parsed { nullptr }; |
171 | | StringView whole_part; |
172 | | StringView fractional_part; |
173 | | }; |
174 | | |
175 | | static constexpr auto max_representable_power_of_ten_in_u64 = 19; |
176 | | static_assert(1e19 <= static_cast<double>(NumericLimits<u64>::max())); |
177 | | static_assert(1e20 >= static_cast<double>(NumericLimits<u64>::max())); |
178 | | |
179 | | static_assert(HostIsLittleEndian, "Float parsing currently assumes little endian, this fact is only used in fast parsing of 8 digits at a time" |
180 | | "\nyou _should_ only need to change read eight_digits to make this big endian compatible."); |
181 | | constexpr u64 read_eight_digits(char const* string) |
182 | 431k | { |
183 | 431k | u64 val; |
184 | 431k | __builtin_memcpy(&val, string, sizeof(val)); |
185 | 431k | return val; |
186 | 431k | } |
187 | | |
188 | | constexpr static bool has_eight_digits(u64 value) |
189 | 0 | { |
190 | | // The ascii digits 0-9 are hex 0x30 - 0x39 |
191 | | |
192 | | // If x is within that range then y := x + 0x46 is 0x76 to 0x7f |
193 | | // z := x - 0x30 is 0x00 - 0x09 |
194 | | // y | z = 0x7t where t is in the range 0 - f so doing & 0x80 gives 0 |
195 | | |
196 | | // However if a character x is below 0x30 then x - 0x30 underflows setting |
197 | | // the 0x80 bit of the next digit meaning & 0x80 will never be 0. |
198 | | |
199 | | // Similarly if a character x is above 0x39 then x + 0x46 gives at least |
200 | | // 0x80 thus & 0x80 will not be zero. |
201 | |
|
202 | 0 | return (((value + 0x4646464646464646) | (value - 0x3030303030303030)) & 0x8080808080808080) == 0; |
203 | 0 | } |
204 | | |
205 | | constexpr static u32 eight_digits_to_value(u64 value) |
206 | 369k | { |
207 | | // THIS DOES ABSOLUTELY ASSUME has_eight_digits is true |
208 | | |
209 | | // This trick is based on https://johnnylee-sde.github.io/Fast-numeric-string-to-int/ |
210 | | // FIXME: fast_float uses a slightly different version, but that is far harder |
211 | | // to understand and does not seem to improve performance substantially. |
212 | | // See https://github.com/fastfloat/fast_float/pull/28 |
213 | | |
214 | | // First convert the digits to their respectively numbers (0x30 -> 0x00 etc.) |
215 | 369k | value -= 0x3030303030303030; |
216 | | |
217 | | // Because of little endian the first number will in fact be the least significant |
218 | | // bits of value i.e. "12345678" -> 0x0807060504030201 |
219 | | // This means that we need to shift/multiply each digit with 8 - the byte it is in |
220 | | // So the eight need to go down, and the 01 need to be multiplied with 10000000 |
221 | | |
222 | | // We effectively multiply by 10 and then shift those values to the right (2^8 = 256) |
223 | | // We then shift the values back down, this leads to 4 digits pairs in the 2 byte parts |
224 | | // The values between are "garbage" which we will ignore |
225 | 369k | value = (value * (256 * 10 + 1)) >> 8; |
226 | | // So with our example this gives 0x$$4e$$38$$22$$0c, where $$ is garbage/ignored |
227 | | // In decimal this gives 78 56 34 12 |
228 | | |
229 | | // Now we keep performing the same trick twice more |
230 | | // First * 100 and shift of 16 (2^16 = 65536) and then shift back |
231 | 369k | value = ((value & 0x00FF00FF00FF00FF) * (65536 * 100 + 1)) >> 16; |
232 | | |
233 | | // Again with our example this gives 0x$$$$162e$$$$04d2 |
234 | | // 5678 1234 |
235 | | |
236 | | // And finally with * 10000 and shift of 32 (2^32 = 4294967296) |
237 | 369k | value = ((value & 0x0000FFFF0000FFFF) * (4294967296 * 10000 + 1)) >> 32; |
238 | | |
239 | | // With the example this gives 0x$$$$$$$$00bc614e |
240 | | // 12345678 |
241 | | // Now we just truncate to the lower part |
242 | 369k | return u32(value); |
243 | 369k | } |
244 | | |
245 | | template<typename IsDoneCallback, typename Has8CharsLeftCallback> |
246 | | static BasicParseResult parse_numbers(char const* start, IsDoneCallback is_done, Has8CharsLeftCallback has_eight_chars_to_read) |
247 | 278k | { |
248 | 278k | char const* ptr = start; |
249 | 278k | BasicParseResult result {}; |
250 | | |
251 | 278k | if (start == nullptr || is_done(ptr)) |
252 | 0 | return result; |
253 | | |
254 | 278k | if (*ptr == '-' || *ptr == '+') { |
255 | 100k | result.negative = *ptr == '-'; |
256 | 100k | ++ptr; |
257 | | |
258 | 100k | if (is_done(ptr) || (!is_ascii_digit(*ptr) && *ptr != '.')) |
259 | 0 | return result; |
260 | 100k | } |
261 | | |
262 | 291k | auto const fast_parse_decimal = [&](auto& value) { |
263 | 291k | while (has_eight_chars_to_read(ptr) && has_eight_digits(read_eight_digits(ptr))) { |
264 | 0 | value = 100'000'000 * value + eight_digits_to_value(read_eight_digits(ptr)); |
265 | 0 | ptr += 8; |
266 | 0 | } |
267 | | |
268 | 28.3M | while (!is_done(ptr) && is_ascii_digit(*ptr)) { |
269 | 28.0M | value = 10 * value + (*ptr - '0'); |
270 | 28.0M | ++ptr; |
271 | 28.0M | } |
272 | 291k | }; FloatingPointStringConversions.cpp:_ZZN2AKL13parse_numbersIZNS_26parse_first_floating_pointITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEdEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlRS4_E_clImEEDaSC_ Line | Count | Source | 262 | 291k | auto const fast_parse_decimal = [&](auto& value) { | 263 | 291k | while (has_eight_chars_to_read(ptr) && has_eight_digits(read_eight_digits(ptr))) { | 264 | 0 | value = 100'000'000 * value + eight_digits_to_value(read_eight_digits(ptr)); | 265 | 0 | ptr += 8; | 266 | 0 | } | 267 | | | 268 | 28.3M | while (!is_done(ptr) && is_ascii_digit(*ptr)) { | 269 | 28.0M | value = 10 * value + (*ptr - '0'); | 270 | 28.0M | ++ptr; | 271 | 28.0M | } | 272 | 291k | }; |
Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZN2AKL13parse_numbersIZNS_26parse_first_floating_pointITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEfEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlRS4_E_clImEEDaSC_ Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZN2AKL13parse_numbersIZNS_47parse_first_floating_point_until_zero_characterITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EEPKcEUlS7_E_ZNS1_ITkNS2_13FloatingPointEdEES5_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlRS4_E_clImEEDaSC_ Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZN2AKL13parse_numbersIZNS_47parse_first_floating_point_until_zero_characterITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EEPKcEUlS7_E_ZNS1_ITkNS2_13FloatingPointEfEES5_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlRS4_E_clImEEDaSC_ Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZN2AKL13parse_numbersIZNS_31parse_floating_point_completelyITkNS_8Concepts13FloatingPointEdEENS_8OptionalIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEdEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlRS4_E_clImEEDaSC_ Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZN2AKL13parse_numbersIZNS_31parse_floating_point_completelyITkNS_8Concepts13FloatingPointEfEENS_8OptionalIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEfEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlRS4_E_clImEEDaSC_ |
273 | | |
274 | 278k | u64 mantissa = 0; |
275 | 278k | auto const* whole_part_start = ptr; |
276 | 278k | fast_parse_decimal(mantissa); |
277 | 278k | auto const* whole_part_end = ptr; |
278 | 278k | auto digits_found = whole_part_end - whole_part_start; |
279 | 278k | result.whole_part = StringView(whole_part_start, digits_found); |
280 | | |
281 | 278k | i64 exponent = 0; |
282 | 278k | auto const* start_of_fractional_part = ptr; |
283 | 278k | if (!is_done(ptr) && *ptr == '.') { |
284 | 13.0k | ++ptr; |
285 | 13.0k | ++start_of_fractional_part; |
286 | 13.0k | fast_parse_decimal(mantissa); |
287 | | |
288 | | // We parsed x digits after the dot so need to multiply with 10^-x |
289 | 13.0k | exponent = -(ptr - start_of_fractional_part); |
290 | 13.0k | } |
291 | 278k | result.fractional_part = StringView(start_of_fractional_part, ptr - start_of_fractional_part); |
292 | 278k | digits_found += -exponent; |
293 | | |
294 | | // If both the part |
295 | 278k | if (digits_found == 0) |
296 | 0 | return result; |
297 | | |
298 | 278k | i64 explicit_exponent = 0; |
299 | | |
300 | | // We do this in a lambda to easily be able to get out of parsing the exponent |
301 | | // and resetting the final character read to before the 'e'. |
302 | 278k | [&] { |
303 | 278k | if (is_done(ptr)) |
304 | 1.34k | return; |
305 | 276k | if (*ptr != 'e' && *ptr != 'E') |
306 | 13.8k | return; |
307 | | |
308 | 262k | auto* pointer_before_e = ptr; |
309 | 262k | ArmedScopeGuard reset_ptr { [&] { ptr = pointer_before_e; } };FloatingPointStringConversions.cpp:_ZZZN2AKL13parse_numbersIZNS_26parse_first_floating_pointITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEdEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlvE_clEvENKUlvE_clEv Line | Count | Source | 309 | 17 | ArmedScopeGuard reset_ptr { [&] { ptr = pointer_before_e; } }; |
Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZZN2AKL13parse_numbersIZNS_26parse_first_floating_pointITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEfEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlvE_clEvENKUlvE_clEv Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZZN2AKL13parse_numbersIZNS_47parse_first_floating_point_until_zero_characterITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EEPKcEUlS7_E_ZNS1_ITkNS2_13FloatingPointEdEES5_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlvE_clEvENKUlvE_clEv Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZZN2AKL13parse_numbersIZNS_47parse_first_floating_point_until_zero_characterITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EEPKcEUlS7_E_ZNS1_ITkNS2_13FloatingPointEfEES5_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlvE_clEvENKUlvE_clEv Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZZN2AKL13parse_numbersIZNS_31parse_floating_point_completelyITkNS_8Concepts13FloatingPointEdEENS_8OptionalIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEdEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlvE_clEvENKUlvE_clEv Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZZN2AKL13parse_numbersIZNS_31parse_floating_point_completelyITkNS_8Concepts13FloatingPointEfEENS_8OptionalIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEfEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlvE_clEvENKUlvE_clEv |
310 | 262k | ++ptr; |
311 | | |
312 | 262k | if (is_done(ptr)) |
313 | 1 | return; |
314 | | |
315 | 262k | bool negative_exponent = false; |
316 | 262k | if (*ptr == '-' || *ptr == '+') { |
317 | 19.4k | negative_exponent = *ptr == '-'; |
318 | 19.4k | ++ptr; |
319 | | |
320 | 19.4k | if (is_done(ptr)) |
321 | 1 | return; |
322 | 19.4k | } |
323 | | |
324 | 262k | if (!is_ascii_digit(*ptr)) |
325 | 15 | return; |
326 | | |
327 | | // Now we must have an optional sign and at least one digit so we |
328 | | // will not reset |
329 | 262k | reset_ptr.disarm(); |
330 | | |
331 | 774k | while (!is_done(ptr) && is_ascii_digit(*ptr)) { |
332 | | // A massive exponent is not really a problem as this would |
333 | | // require a lot of characters so we would fallback on precise |
334 | | // parsing anyway (this is already 268435456 digits or 10 megabytes of digits) |
335 | 511k | if (explicit_exponent < 0x10'000'000) |
336 | 504k | explicit_exponent = 10 * explicit_exponent + (*ptr - '0'); |
337 | | |
338 | 511k | ++ptr; |
339 | 511k | } |
340 | | |
341 | 262k | explicit_exponent = negative_exponent ? -explicit_exponent : explicit_exponent; |
342 | 262k | exponent += explicit_exponent; |
343 | 262k | }(); FloatingPointStringConversions.cpp:_ZZN2AKL13parse_numbersIZNS_26parse_first_floating_pointITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEdEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlvE_clEv Line | Count | Source | 302 | 278k | [&] { | 303 | 278k | if (is_done(ptr)) | 304 | 1.34k | return; | 305 | 276k | if (*ptr != 'e' && *ptr != 'E') | 306 | 13.8k | return; | 307 | | | 308 | 262k | auto* pointer_before_e = ptr; | 309 | 262k | ArmedScopeGuard reset_ptr { [&] { ptr = pointer_before_e; } }; | 310 | 262k | ++ptr; | 311 | | | 312 | 262k | if (is_done(ptr)) | 313 | 1 | return; | 314 | | | 315 | 262k | bool negative_exponent = false; | 316 | 262k | if (*ptr == '-' || *ptr == '+') { | 317 | 19.4k | negative_exponent = *ptr == '-'; | 318 | 19.4k | ++ptr; | 319 | | | 320 | 19.4k | if (is_done(ptr)) | 321 | 1 | return; | 322 | 19.4k | } | 323 | | | 324 | 262k | if (!is_ascii_digit(*ptr)) | 325 | 15 | return; | 326 | | | 327 | | // Now we must have an optional sign and at least one digit so we | 328 | | // will not reset | 329 | 262k | reset_ptr.disarm(); | 330 | | | 331 | 774k | while (!is_done(ptr) && is_ascii_digit(*ptr)) { | 332 | | // A massive exponent is not really a problem as this would | 333 | | // require a lot of characters so we would fallback on precise | 334 | | // parsing anyway (this is already 268435456 digits or 10 megabytes of digits) | 335 | 511k | if (explicit_exponent < 0x10'000'000) | 336 | 504k | explicit_exponent = 10 * explicit_exponent + (*ptr - '0'); | 337 | | | 338 | 511k | ++ptr; | 339 | 511k | } | 340 | | | 341 | 262k | explicit_exponent = negative_exponent ? -explicit_exponent : explicit_exponent; | 342 | 262k | exponent += explicit_exponent; | 343 | 262k | }(); |
Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZN2AKL13parse_numbersIZNS_26parse_first_floating_pointITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEfEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlvE_clEv Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZN2AKL13parse_numbersIZNS_47parse_first_floating_point_until_zero_characterITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EEPKcEUlS7_E_ZNS1_ITkNS2_13FloatingPointEdEES5_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlvE_clEv Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZN2AKL13parse_numbersIZNS_47parse_first_floating_point_until_zero_characterITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EEPKcEUlS7_E_ZNS1_ITkNS2_13FloatingPointEfEES5_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlvE_clEv Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZN2AKL13parse_numbersIZNS_31parse_floating_point_completelyITkNS_8Concepts13FloatingPointEdEENS_8OptionalIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEdEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlvE_clEv Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZN2AKL13parse_numbersIZNS_31parse_floating_point_completelyITkNS_8Concepts13FloatingPointEfEENS_8OptionalIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEfEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ENKUlvE_clEv |
344 | | |
345 | 278k | result.valid = true; |
346 | 278k | result.last_parsed = ptr; |
347 | | |
348 | 278k | if (digits_found > max_representable_power_of_ten_in_u64) { |
349 | | // There could be overflow but because we just count the digits it could be leading zeros |
350 | 15.9k | auto const* leading_digit = whole_part_start; |
351 | 1.45M | while (!is_done(leading_digit) && (*leading_digit == '0' || *leading_digit == '.')) { |
352 | 1.44M | if (*leading_digit == '0') |
353 | 1.43M | --digits_found; |
354 | | |
355 | 1.44M | ++leading_digit; |
356 | 1.44M | } |
357 | | |
358 | 15.9k | if (digits_found > max_representable_power_of_ten_in_u64) { |
359 | | // FIXME: We just removed leading zeros, we might be able to skip these easily again. |
360 | | // If removing the leading zeros does not help we reparse and keep just the significant digits |
361 | 15.6k | result.more_than_19_digits_with_overflow = true; |
362 | | |
363 | 15.6k | mantissa = 0; |
364 | 15.6k | constexpr i64 smallest_nineteen_digit_number = { 1000000000000000000 }; |
365 | 15.6k | char const* reparse_ptr = whole_part_start; |
366 | | |
367 | 15.6k | constexpr i64 smallest_eleven_digit_number = { 10000000000 }; |
368 | 40.5k | while (mantissa < smallest_eleven_digit_number && (whole_part_end - reparse_ptr) >= 8) { |
369 | 24.9k | mantissa = 100'000'000 * mantissa + eight_digits_to_value(read_eight_digits(reparse_ptr)); |
370 | 24.9k | reparse_ptr += 8; |
371 | 24.9k | } |
372 | | |
373 | 54.8k | while (mantissa < smallest_nineteen_digit_number && reparse_ptr != whole_part_end) { |
374 | 39.2k | mantissa = 10 * mantissa + (*reparse_ptr - '0'); |
375 | 39.2k | ++reparse_ptr; |
376 | 39.2k | } |
377 | | |
378 | 15.6k | if (mantissa >= smallest_nineteen_digit_number) { |
379 | | // We still needed to parse (whole_part_end - reparse_ptr) digits so scale the exponent |
380 | 10.3k | exponent = explicit_exponent + (whole_part_end - reparse_ptr); |
381 | 10.3k | } else { |
382 | 5.23k | reparse_ptr = start_of_fractional_part; |
383 | 5.23k | char const* fractional_end = result.fractional_part.characters_without_null_termination() + result.fractional_part.length(); |
384 | | |
385 | 58.5k | while (mantissa < smallest_eleven_digit_number && (fractional_end - reparse_ptr) >= 8) { |
386 | 53.3k | mantissa = 100'000'000 * mantissa + eight_digits_to_value(read_eight_digits(reparse_ptr)); |
387 | 53.3k | reparse_ptr += 8; |
388 | 53.3k | } |
389 | | |
390 | 21.3k | while (mantissa < smallest_nineteen_digit_number && reparse_ptr != fractional_end) { |
391 | 16.1k | mantissa = 10 * mantissa + (*reparse_ptr - '0'); |
392 | 16.1k | ++reparse_ptr; |
393 | 16.1k | } |
394 | | |
395 | | // Again we might be truncating fractional number so scale the exponent with that |
396 | | // However here need to subtract 1 from the exponent for every fractional digit |
397 | 5.23k | exponent = explicit_exponent - (reparse_ptr - start_of_fractional_part); |
398 | 5.23k | } |
399 | 15.6k | } |
400 | 15.9k | } |
401 | | |
402 | 278k | result.mantissa = mantissa; |
403 | 278k | result.exponent = exponent; |
404 | 278k | return result; |
405 | 278k | } FloatingPointStringConversions.cpp:_ZN2AKL13parse_numbersIZNS_26parse_first_floating_pointITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEdEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ Line | Count | Source | 247 | 278k | { | 248 | 278k | char const* ptr = start; | 249 | 278k | BasicParseResult result {}; | 250 | | | 251 | 278k | if (start == nullptr || is_done(ptr)) | 252 | 0 | return result; | 253 | | | 254 | 278k | if (*ptr == '-' || *ptr == '+') { | 255 | 100k | result.negative = *ptr == '-'; | 256 | 100k | ++ptr; | 257 | | | 258 | 100k | if (is_done(ptr) || (!is_ascii_digit(*ptr) && *ptr != '.')) | 259 | 0 | return result; | 260 | 100k | } | 261 | | | 262 | 278k | auto const fast_parse_decimal = [&](auto& value) { | 263 | 278k | while (has_eight_chars_to_read(ptr) && has_eight_digits(read_eight_digits(ptr))) { | 264 | 278k | value = 100'000'000 * value + eight_digits_to_value(read_eight_digits(ptr)); | 265 | 278k | ptr += 8; | 266 | 278k | } | 267 | | | 268 | 278k | while (!is_done(ptr) && is_ascii_digit(*ptr)) { | 269 | 278k | value = 10 * value + (*ptr - '0'); | 270 | 278k | ++ptr; | 271 | 278k | } | 272 | 278k | }; | 273 | | | 274 | 278k | u64 mantissa = 0; | 275 | 278k | auto const* whole_part_start = ptr; | 276 | 278k | fast_parse_decimal(mantissa); | 277 | 278k | auto const* whole_part_end = ptr; | 278 | 278k | auto digits_found = whole_part_end - whole_part_start; | 279 | 278k | result.whole_part = StringView(whole_part_start, digits_found); | 280 | | | 281 | 278k | i64 exponent = 0; | 282 | 278k | auto const* start_of_fractional_part = ptr; | 283 | 278k | if (!is_done(ptr) && *ptr == '.') { | 284 | 13.0k | ++ptr; | 285 | 13.0k | ++start_of_fractional_part; | 286 | 13.0k | fast_parse_decimal(mantissa); | 287 | | | 288 | | // We parsed x digits after the dot so need to multiply with 10^-x | 289 | 13.0k | exponent = -(ptr - start_of_fractional_part); | 290 | 13.0k | } | 291 | 278k | result.fractional_part = StringView(start_of_fractional_part, ptr - start_of_fractional_part); | 292 | 278k | digits_found += -exponent; | 293 | | | 294 | | // If both the part | 295 | 278k | if (digits_found == 0) | 296 | 0 | return result; | 297 | | | 298 | 278k | i64 explicit_exponent = 0; | 299 | | | 300 | | // We do this in a lambda to easily be able to get out of parsing the exponent | 301 | | // and resetting the final character read to before the 'e'. | 302 | 278k | [&] { | 303 | 278k | if (is_done(ptr)) | 304 | 278k | return; | 305 | 278k | if (*ptr != 'e' && *ptr != 'E') | 306 | 278k | return; | 307 | | | 308 | 278k | auto* pointer_before_e = ptr; | 309 | 278k | ArmedScopeGuard reset_ptr { [&] { ptr = pointer_before_e; } }; | 310 | 278k | ++ptr; | 311 | | | 312 | 278k | if (is_done(ptr)) | 313 | 278k | return; | 314 | | | 315 | 278k | bool negative_exponent = false; | 316 | 278k | if (*ptr == '-' || *ptr == '+') { | 317 | 278k | negative_exponent = *ptr == '-'; | 318 | 278k | ++ptr; | 319 | | | 320 | 278k | if (is_done(ptr)) | 321 | 278k | return; | 322 | 278k | } | 323 | | | 324 | 278k | if (!is_ascii_digit(*ptr)) | 325 | 278k | return; | 326 | | | 327 | | // Now we must have an optional sign and at least one digit so we | 328 | | // will not reset | 329 | 278k | reset_ptr.disarm(); | 330 | | | 331 | 278k | while (!is_done(ptr) && is_ascii_digit(*ptr)) { | 332 | | // A massive exponent is not really a problem as this would | 333 | | // require a lot of characters so we would fallback on precise | 334 | | // parsing anyway (this is already 268435456 digits or 10 megabytes of digits) | 335 | 278k | if (explicit_exponent < 0x10'000'000) | 336 | 278k | explicit_exponent = 10 * explicit_exponent + (*ptr - '0'); | 337 | | | 338 | 278k | ++ptr; | 339 | 278k | } | 340 | | | 341 | 278k | explicit_exponent = negative_exponent ? -explicit_exponent : explicit_exponent; | 342 | 278k | exponent += explicit_exponent; | 343 | 278k | }(); | 344 | | | 345 | 278k | result.valid = true; | 346 | 278k | result.last_parsed = ptr; | 347 | | | 348 | 278k | if (digits_found > max_representable_power_of_ten_in_u64) { | 349 | | // There could be overflow but because we just count the digits it could be leading zeros | 350 | 15.9k | auto const* leading_digit = whole_part_start; | 351 | 1.45M | while (!is_done(leading_digit) && (*leading_digit == '0' || *leading_digit == '.')) { | 352 | 1.44M | if (*leading_digit == '0') | 353 | 1.43M | --digits_found; | 354 | | | 355 | 1.44M | ++leading_digit; | 356 | 1.44M | } | 357 | | | 358 | 15.9k | if (digits_found > max_representable_power_of_ten_in_u64) { | 359 | | // FIXME: We just removed leading zeros, we might be able to skip these easily again. | 360 | | // If removing the leading zeros does not help we reparse and keep just the significant digits | 361 | 15.6k | result.more_than_19_digits_with_overflow = true; | 362 | | | 363 | 15.6k | mantissa = 0; | 364 | 15.6k | constexpr i64 smallest_nineteen_digit_number = { 1000000000000000000 }; | 365 | 15.6k | char const* reparse_ptr = whole_part_start; | 366 | | | 367 | 15.6k | constexpr i64 smallest_eleven_digit_number = { 10000000000 }; | 368 | 40.5k | while (mantissa < smallest_eleven_digit_number && (whole_part_end - reparse_ptr) >= 8) { | 369 | 24.9k | mantissa = 100'000'000 * mantissa + eight_digits_to_value(read_eight_digits(reparse_ptr)); | 370 | 24.9k | reparse_ptr += 8; | 371 | 24.9k | } | 372 | | | 373 | 54.8k | while (mantissa < smallest_nineteen_digit_number && reparse_ptr != whole_part_end) { | 374 | 39.2k | mantissa = 10 * mantissa + (*reparse_ptr - '0'); | 375 | 39.2k | ++reparse_ptr; | 376 | 39.2k | } | 377 | | | 378 | 15.6k | if (mantissa >= smallest_nineteen_digit_number) { | 379 | | // We still needed to parse (whole_part_end - reparse_ptr) digits so scale the exponent | 380 | 10.3k | exponent = explicit_exponent + (whole_part_end - reparse_ptr); | 381 | 10.3k | } else { | 382 | 5.23k | reparse_ptr = start_of_fractional_part; | 383 | 5.23k | char const* fractional_end = result.fractional_part.characters_without_null_termination() + result.fractional_part.length(); | 384 | | | 385 | 58.5k | while (mantissa < smallest_eleven_digit_number && (fractional_end - reparse_ptr) >= 8) { | 386 | 53.3k | mantissa = 100'000'000 * mantissa + eight_digits_to_value(read_eight_digits(reparse_ptr)); | 387 | 53.3k | reparse_ptr += 8; | 388 | 53.3k | } | 389 | | | 390 | 21.3k | while (mantissa < smallest_nineteen_digit_number && reparse_ptr != fractional_end) { | 391 | 16.1k | mantissa = 10 * mantissa + (*reparse_ptr - '0'); | 392 | 16.1k | ++reparse_ptr; | 393 | 16.1k | } | 394 | | | 395 | | // Again we might be truncating fractional number so scale the exponent with that | 396 | | // However here need to subtract 1 from the exponent for every fractional digit | 397 | 5.23k | exponent = explicit_exponent - (reparse_ptr - start_of_fractional_part); | 398 | 5.23k | } | 399 | 15.6k | } | 400 | 15.9k | } | 401 | | | 402 | 278k | result.mantissa = mantissa; | 403 | 278k | result.exponent = exponent; | 404 | 278k | return result; | 405 | 278k | } |
Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZN2AKL13parse_numbersIZNS_26parse_first_floating_pointITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEfEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZN2AKL13parse_numbersIZNS_47parse_first_floating_point_until_zero_characterITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EEPKcEUlS7_E_ZNS1_ITkNS2_13FloatingPointEdEES5_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZN2AKL13parse_numbersIZNS_47parse_first_floating_point_until_zero_characterITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EEPKcEUlS7_E_ZNS1_ITkNS2_13FloatingPointEfEES5_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZN2AKL13parse_numbersIZNS_31parse_floating_point_completelyITkNS_8Concepts13FloatingPointEdEENS_8OptionalIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEdEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZN2AKL13parse_numbersIZNS_31parse_floating_point_completelyITkNS_8Concepts13FloatingPointEfEENS_8OptionalIT_EEPKcS7_EUlS7_E_ZNS1_ITkNS2_13FloatingPointEfEES5_S7_S7_EUlS7_E0_EENS_16BasicParseResultES7_S4_T0_ |
406 | | |
407 | | constexpr static u128 compute_power_of_five(i64 exponent) |
408 | 0 | { |
409 | 0 | constexpr u4096 bit128 = u4096 { 1u } << 127u; |
410 | 0 | constexpr u4096 bit129 = u4096 { 1u } << 128u; |
411 | 0 |
|
412 | 0 | VERIFY(exponent <= 308); |
413 | 0 | VERIFY(exponent >= -342); |
414 | 0 |
|
415 | 0 | if (exponent >= 0) { |
416 | 0 | u4096 base { 1u }; |
417 | 0 | for (auto i = 0u; i < exponent; ++i) { |
418 | 0 | base *= 5u; |
419 | 0 | } |
420 | 0 |
|
421 | 0 | while (base < bit128) |
422 | 0 | base <<= 1u; |
423 | 0 | while (base >= bit129) |
424 | 0 | base >>= 1u; |
425 | 0 |
|
426 | 0 | return u128 { base }; |
427 | 0 | } |
428 | 0 |
|
429 | 0 | exponent *= -1; |
430 | 0 | if (exponent <= 27) { |
431 | 0 | u4096 base { 1u }; |
432 | 0 | for (auto i = 0u; i < exponent; ++i) { |
433 | 0 | base *= 5u; |
434 | 0 | } |
435 | 0 |
|
436 | 0 | auto z = 4096 - base.clz(); |
437 | 0 |
|
438 | 0 | auto b = z + 127; |
439 | 0 | u4096 base2 { 1u }; |
440 | 0 | for (auto i = 0u; i < b; ++i) { |
441 | 0 | base2 *= 2u; |
442 | 0 | } |
443 | 0 |
|
444 | 0 | base2 /= base; |
445 | 0 | base2 += 1u; |
446 | 0 |
|
447 | 0 | return u128 { base2 }; |
448 | 0 | } |
449 | 0 |
|
450 | 0 | VERIFY(exponent <= 342); |
451 | 0 | VERIFY(exponent >= 28); |
452 | 0 |
|
453 | 0 | u4096 base { 1u }; |
454 | 0 | for (auto i = 0u; i < exponent; ++i) { |
455 | 0 | base *= 5u; |
456 | 0 | } |
457 | 0 |
|
458 | 0 | auto z = 4096 - base.clz(); |
459 | 0 |
|
460 | 0 | auto b = 2 * z + 128; |
461 | 0 |
|
462 | 0 | u4096 base2 { 1u }; |
463 | 0 | for (auto i = 0u; i < b; ++i) { |
464 | 0 | base2 *= 2u; |
465 | 0 | } |
466 | 0 |
|
467 | 0 | base2 /= base; |
468 | 0 | base2 += 1u; |
469 | 0 |
|
470 | 0 | while (base2 >= bit129) |
471 | 0 | base2 >>= 1u; |
472 | 0 |
|
473 | 0 | return u128 { base2 }; |
474 | 0 | } |
475 | | |
476 | | static constexpr i64 lowest_exponent = -342; |
477 | | static constexpr i64 highest_exponent = 308; |
478 | | |
479 | | constexpr auto pre_compute_table() |
480 | 0 | { |
481 | 0 | // Computing this entire table at compile time is slow and hits constexpr |
482 | 0 | // limits, so we just compute a (the simplest) value to make sure the |
483 | 0 | // function is used. This table can thus be generated with the function |
484 | 0 | // `u128 compute_power_of_five(i64 exponent)` above. |
485 | 0 | AK::Array<u128, highest_exponent - lowest_exponent + 1> values = { |
486 | 0 | u128 { 0x113faa2906a13b3fULL, 0xeef453d6923bd65aULL }, |
487 | 0 | u128 { 0x4ac7ca59a424c507ULL, 0x9558b4661b6565f8ULL }, |
488 | 0 | u128 { 0x5d79bcf00d2df649ULL, 0xbaaee17fa23ebf76ULL }, |
489 | 0 | u128 { 0xf4d82c2c107973dcULL, 0xe95a99df8ace6f53ULL }, |
490 | 0 | u128 { 0x79071b9b8a4be869ULL, 0x91d8a02bb6c10594ULL }, |
491 | 0 | u128 { 0x9748e2826cdee284ULL, 0xb64ec836a47146f9ULL }, |
492 | 0 | u128 { 0xfd1b1b2308169b25ULL, 0xe3e27a444d8d98b7ULL }, |
493 | 0 | u128 { 0xfe30f0f5e50e20f7ULL, 0x8e6d8c6ab0787f72ULL }, |
494 | 0 | u128 { 0xbdbd2d335e51a935ULL, 0xb208ef855c969f4fULL }, |
495 | 0 | u128 { 0xad2c788035e61382ULL, 0xde8b2b66b3bc4723ULL }, |
496 | 0 | u128 { 0x4c3bcb5021afcc31ULL, 0x8b16fb203055ac76ULL }, |
497 | 0 | u128 { 0xdf4abe242a1bbf3dULL, 0xaddcb9e83c6b1793ULL }, |
498 | 0 | u128 { 0xd71d6dad34a2af0dULL, 0xd953e8624b85dd78ULL }, |
499 | 0 | u128 { 0x8672648c40e5ad68ULL, 0x87d4713d6f33aa6bULL }, |
500 | 0 | u128 { 0x680efdaf511f18c2ULL, 0xa9c98d8ccb009506ULL }, |
501 | 0 | u128 { 0x212bd1b2566def2ULL, 0xd43bf0effdc0ba48ULL }, |
502 | 0 | u128 { 0x14bb630f7604b57ULL, 0x84a57695fe98746dULL }, |
503 | 0 | u128 { 0x419ea3bd35385e2dULL, 0xa5ced43b7e3e9188ULL }, |
504 | 0 | u128 { 0x52064cac828675b9ULL, 0xcf42894a5dce35eaULL }, |
505 | 0 | u128 { 0x7343efebd1940993ULL, 0x818995ce7aa0e1b2ULL }, |
506 | 0 | u128 { 0x1014ebe6c5f90bf8ULL, 0xa1ebfb4219491a1fULL }, |
507 | 0 | u128 { 0xd41a26e077774ef6ULL, 0xca66fa129f9b60a6ULL }, |
508 | 0 | u128 { 0x8920b098955522b4ULL, 0xfd00b897478238d0ULL }, |
509 | 0 | u128 { 0x55b46e5f5d5535b0ULL, 0x9e20735e8cb16382ULL }, |
510 | 0 | u128 { 0xeb2189f734aa831dULL, 0xc5a890362fddbc62ULL }, |
511 | 0 | u128 { 0xa5e9ec7501d523e4ULL, 0xf712b443bbd52b7bULL }, |
512 | 0 | u128 { 0x47b233c92125366eULL, 0x9a6bb0aa55653b2dULL }, |
513 | 0 | u128 { 0x999ec0bb696e840aULL, 0xc1069cd4eabe89f8ULL }, |
514 | 0 | u128 { 0xc00670ea43ca250dULL, 0xf148440a256e2c76ULL }, |
515 | 0 | u128 { 0x380406926a5e5728ULL, 0x96cd2a865764dbcaULL }, |
516 | 0 | u128 { 0xc605083704f5ecf2ULL, 0xbc807527ed3e12bcULL }, |
517 | 0 | u128 { 0xf7864a44c633682eULL, 0xeba09271e88d976bULL }, |
518 | 0 | u128 { 0x7ab3ee6afbe0211dULL, 0x93445b8731587ea3ULL }, |
519 | 0 | u128 { 0x5960ea05bad82964ULL, 0xb8157268fdae9e4cULL }, |
520 | 0 | u128 { 0x6fb92487298e33bdULL, 0xe61acf033d1a45dfULL }, |
521 | 0 | u128 { 0xa5d3b6d479f8e056ULL, 0x8fd0c16206306babULL }, |
522 | 0 | u128 { 0x8f48a4899877186cULL, 0xb3c4f1ba87bc8696ULL }, |
523 | 0 | u128 { 0x331acdabfe94de87ULL, 0xe0b62e2929aba83cULL }, |
524 | 0 | u128 { 0x9ff0c08b7f1d0b14ULL, 0x8c71dcd9ba0b4925ULL }, |
525 | 0 | u128 { 0x7ecf0ae5ee44dd9ULL, 0xaf8e5410288e1b6fULL }, |
526 | 0 | u128 { 0xc9e82cd9f69d6150ULL, 0xdb71e91432b1a24aULL }, |
527 | 0 | u128 { 0xbe311c083a225cd2ULL, 0x892731ac9faf056eULL }, |
528 | 0 | u128 { 0x6dbd630a48aaf406ULL, 0xab70fe17c79ac6caULL }, |
529 | 0 | u128 { 0x92cbbccdad5b108ULL, 0xd64d3d9db981787dULL }, |
530 | 0 | u128 { 0x25bbf56008c58ea5ULL, 0x85f0468293f0eb4eULL }, |
531 | 0 | u128 { 0xaf2af2b80af6f24eULL, 0xa76c582338ed2621ULL }, |
532 | 0 | u128 { 0x1af5af660db4aee1ULL, 0xd1476e2c07286faaULL }, |
533 | 0 | u128 { 0x50d98d9fc890ed4dULL, 0x82cca4db847945caULL }, |
534 | 0 | u128 { 0xe50ff107bab528a0ULL, 0xa37fce126597973cULL }, |
535 | 0 | u128 { 0x1e53ed49a96272c8ULL, 0xcc5fc196fefd7d0cULL }, |
536 | 0 | u128 { 0x25e8e89c13bb0f7aULL, 0xff77b1fcbebcdc4fULL }, |
537 | 0 | u128 { 0x77b191618c54e9acULL, 0x9faacf3df73609b1ULL }, |
538 | 0 | u128 { 0xd59df5b9ef6a2417ULL, 0xc795830d75038c1dULL }, |
539 | 0 | u128 { 0x4b0573286b44ad1dULL, 0xf97ae3d0d2446f25ULL }, |
540 | 0 | u128 { 0x4ee367f9430aec32ULL, 0x9becce62836ac577ULL }, |
541 | 0 | u128 { 0x229c41f793cda73fULL, 0xc2e801fb244576d5ULL }, |
542 | 0 | u128 { 0x6b43527578c1110fULL, 0xf3a20279ed56d48aULL }, |
543 | 0 | u128 { 0x830a13896b78aaa9ULL, 0x9845418c345644d6ULL }, |
544 | 0 | u128 { 0x23cc986bc656d553ULL, 0xbe5691ef416bd60cULL }, |
545 | 0 | u128 { 0x2cbfbe86b7ec8aa8ULL, 0xedec366b11c6cb8fULL }, |
546 | 0 | u128 { 0x7bf7d71432f3d6a9ULL, 0x94b3a202eb1c3f39ULL }, |
547 | 0 | u128 { 0xdaf5ccd93fb0cc53ULL, 0xb9e08a83a5e34f07ULL }, |
548 | 0 | u128 { 0xd1b3400f8f9cff68ULL, 0xe858ad248f5c22c9ULL }, |
549 | 0 | u128 { 0x23100809b9c21fa1ULL, 0x91376c36d99995beULL }, |
550 | 0 | u128 { 0xabd40a0c2832a78aULL, 0xb58547448ffffb2dULL }, |
551 | 0 | u128 { 0x16c90c8f323f516cULL, 0xe2e69915b3fff9f9ULL }, |
552 | 0 | u128 { 0xae3da7d97f6792e3ULL, 0x8dd01fad907ffc3bULL }, |
553 | 0 | u128 { 0x99cd11cfdf41779cULL, 0xb1442798f49ffb4aULL }, |
554 | 0 | u128 { 0x40405643d711d583ULL, 0xdd95317f31c7fa1dULL }, |
555 | 0 | u128 { 0x482835ea666b2572ULL, 0x8a7d3eef7f1cfc52ULL }, |
556 | 0 | u128 { 0xda3243650005eecfULL, 0xad1c8eab5ee43b66ULL }, |
557 | 0 | u128 { 0x90bed43e40076a82ULL, 0xd863b256369d4a40ULL }, |
558 | 0 | u128 { 0x5a7744a6e804a291ULL, 0x873e4f75e2224e68ULL }, |
559 | 0 | u128 { 0x711515d0a205cb36ULL, 0xa90de3535aaae202ULL }, |
560 | 0 | u128 { 0xd5a5b44ca873e03ULL, 0xd3515c2831559a83ULL }, |
561 | 0 | u128 { 0xe858790afe9486c2ULL, 0x8412d9991ed58091ULL }, |
562 | 0 | u128 { 0x626e974dbe39a872ULL, 0xa5178fff668ae0b6ULL }, |
563 | 0 | u128 { 0xfb0a3d212dc8128fULL, 0xce5d73ff402d98e3ULL }, |
564 | 0 | u128 { 0x7ce66634bc9d0b99ULL, 0x80fa687f881c7f8eULL }, |
565 | 0 | u128 { 0x1c1fffc1ebc44e80ULL, 0xa139029f6a239f72ULL }, |
566 | 0 | u128 { 0xa327ffb266b56220ULL, 0xc987434744ac874eULL }, |
567 | 0 | u128 { 0x4bf1ff9f0062baa8ULL, 0xfbe9141915d7a922ULL }, |
568 | 0 | u128 { 0x6f773fc3603db4a9ULL, 0x9d71ac8fada6c9b5ULL }, |
569 | 0 | u128 { 0xcb550fb4384d21d3ULL, 0xc4ce17b399107c22ULL }, |
570 | 0 | u128 { 0x7e2a53a146606a48ULL, 0xf6019da07f549b2bULL }, |
571 | 0 | u128 { 0x2eda7444cbfc426dULL, 0x99c102844f94e0fbULL }, |
572 | 0 | u128 { 0xfa911155fefb5308ULL, 0xc0314325637a1939ULL }, |
573 | 0 | u128 { 0x793555ab7eba27caULL, 0xf03d93eebc589f88ULL }, |
574 | 0 | u128 { 0x4bc1558b2f3458deULL, 0x96267c7535b763b5ULL }, |
575 | 0 | u128 { 0x9eb1aaedfb016f16ULL, 0xbbb01b9283253ca2ULL }, |
576 | 0 | u128 { 0x465e15a979c1cadcULL, 0xea9c227723ee8bcbULL }, |
577 | 0 | u128 { 0xbfacd89ec191ec9ULL, 0x92a1958a7675175fULL }, |
578 | 0 | u128 { 0xcef980ec671f667bULL, 0xb749faed14125d36ULL }, |
579 | 0 | u128 { 0x82b7e12780e7401aULL, 0xe51c79a85916f484ULL }, |
580 | 0 | u128 { 0xd1b2ecb8b0908810ULL, 0x8f31cc0937ae58d2ULL }, |
581 | 0 | u128 { 0x861fa7e6dcb4aa15ULL, 0xb2fe3f0b8599ef07ULL }, |
582 | 0 | u128 { 0x67a791e093e1d49aULL, 0xdfbdcece67006ac9ULL }, |
583 | 0 | u128 { 0xe0c8bb2c5c6d24e0ULL, 0x8bd6a141006042bdULL }, |
584 | 0 | u128 { 0x58fae9f773886e18ULL, 0xaecc49914078536dULL }, |
585 | 0 | u128 { 0xaf39a475506a899eULL, 0xda7f5bf590966848ULL }, |
586 | 0 | u128 { 0x6d8406c952429603ULL, 0x888f99797a5e012dULL }, |
587 | 0 | u128 { 0xc8e5087ba6d33b83ULL, 0xaab37fd7d8f58178ULL }, |
588 | 0 | u128 { 0xfb1e4a9a90880a64ULL, 0xd5605fcdcf32e1d6ULL }, |
589 | 0 | u128 { 0x5cf2eea09a55067fULL, 0x855c3be0a17fcd26ULL }, |
590 | 0 | u128 { 0xf42faa48c0ea481eULL, 0xa6b34ad8c9dfc06fULL }, |
591 | 0 | u128 { 0xf13b94daf124da26ULL, 0xd0601d8efc57b08bULL }, |
592 | 0 | u128 { 0x76c53d08d6b70858ULL, 0x823c12795db6ce57ULL }, |
593 | 0 | u128 { 0x54768c4b0c64ca6eULL, 0xa2cb1717b52481edULL }, |
594 | 0 | u128 { 0xa9942f5dcf7dfd09ULL, 0xcb7ddcdda26da268ULL }, |
595 | 0 | u128 { 0xd3f93b35435d7c4cULL, 0xfe5d54150b090b02ULL }, |
596 | 0 | u128 { 0xc47bc5014a1a6dafULL, 0x9efa548d26e5a6e1ULL }, |
597 | 0 | u128 { 0x359ab6419ca1091bULL, 0xc6b8e9b0709f109aULL }, |
598 | 0 | u128 { 0xc30163d203c94b62ULL, 0xf867241c8cc6d4c0ULL }, |
599 | 0 | u128 { 0x79e0de63425dcf1dULL, 0x9b407691d7fc44f8ULL }, |
600 | 0 | u128 { 0x985915fc12f542e4ULL, 0xc21094364dfb5636ULL }, |
601 | 0 | u128 { 0x3e6f5b7b17b2939dULL, 0xf294b943e17a2bc4ULL }, |
602 | 0 | u128 { 0xa705992ceecf9c42ULL, 0x979cf3ca6cec5b5aULL }, |
603 | 0 | u128 { 0x50c6ff782a838353ULL, 0xbd8430bd08277231ULL }, |
604 | 0 | u128 { 0xa4f8bf5635246428ULL, 0xece53cec4a314ebdULL }, |
605 | 0 | u128 { 0x871b7795e136be99ULL, 0x940f4613ae5ed136ULL }, |
606 | 0 | u128 { 0x28e2557b59846e3fULL, 0xb913179899f68584ULL }, |
607 | 0 | u128 { 0x331aeada2fe589cfULL, 0xe757dd7ec07426e5ULL }, |
608 | 0 | u128 { 0x3ff0d2c85def7621ULL, 0x9096ea6f3848984fULL }, |
609 | 0 | u128 { 0xfed077a756b53a9ULL, 0xb4bca50b065abe63ULL }, |
610 | 0 | u128 { 0xd3e8495912c62894ULL, 0xe1ebce4dc7f16dfbULL }, |
611 | 0 | u128 { 0x64712dd7abbbd95cULL, 0x8d3360f09cf6e4bdULL }, |
612 | 0 | u128 { 0xbd8d794d96aacfb3ULL, 0xb080392cc4349decULL }, |
613 | 0 | u128 { 0xecf0d7a0fc5583a0ULL, 0xdca04777f541c567ULL }, |
614 | 0 | u128 { 0xf41686c49db57244ULL, 0x89e42caaf9491b60ULL }, |
615 | 0 | u128 { 0x311c2875c522ced5ULL, 0xac5d37d5b79b6239ULL }, |
616 | 0 | u128 { 0x7d633293366b828bULL, 0xd77485cb25823ac7ULL }, |
617 | 0 | u128 { 0xae5dff9c02033197ULL, 0x86a8d39ef77164bcULL }, |
618 | 0 | u128 { 0xd9f57f830283fdfcULL, 0xa8530886b54dbdebULL }, |
619 | 0 | u128 { 0xd072df63c324fd7bULL, 0xd267caa862a12d66ULL }, |
620 | 0 | u128 { 0x4247cb9e59f71e6dULL, 0x8380dea93da4bc60ULL }, |
621 | 0 | u128 { 0x52d9be85f074e608ULL, 0xa46116538d0deb78ULL }, |
622 | 0 | u128 { 0x67902e276c921f8bULL, 0xcd795be870516656ULL }, |
623 | 0 | u128 { 0xba1cd8a3db53b6ULL, 0x806bd9714632dff6ULL }, |
624 | 0 | u128 { 0x80e8a40eccd228a4ULL, 0xa086cfcd97bf97f3ULL }, |
625 | 0 | u128 { 0x6122cd128006b2cdULL, 0xc8a883c0fdaf7df0ULL }, |
626 | 0 | u128 { 0x796b805720085f81ULL, 0xfad2a4b13d1b5d6cULL }, |
627 | 0 | u128 { 0xcbe3303674053bb0ULL, 0x9cc3a6eec6311a63ULL }, |
628 | 0 | u128 { 0xbedbfc4411068a9cULL, 0xc3f490aa77bd60fcULL }, |
629 | 0 | u128 { 0xee92fb5515482d44ULL, 0xf4f1b4d515acb93bULL }, |
630 | 0 | u128 { 0x751bdd152d4d1c4aULL, 0x991711052d8bf3c5ULL }, |
631 | 0 | u128 { 0xd262d45a78a0635dULL, 0xbf5cd54678eef0b6ULL }, |
632 | 0 | u128 { 0x86fb897116c87c34ULL, 0xef340a98172aace4ULL }, |
633 | 0 | u128 { 0xd45d35e6ae3d4da0ULL, 0x9580869f0e7aac0eULL }, |
634 | 0 | u128 { 0x8974836059cca109ULL, 0xbae0a846d2195712ULL }, |
635 | 0 | u128 { 0x2bd1a438703fc94bULL, 0xe998d258869facd7ULL }, |
636 | 0 | u128 { 0x7b6306a34627ddcfULL, 0x91ff83775423cc06ULL }, |
637 | 0 | u128 { 0x1a3bc84c17b1d542ULL, 0xb67f6455292cbf08ULL }, |
638 | 0 | u128 { 0x20caba5f1d9e4a93ULL, 0xe41f3d6a7377eecaULL }, |
639 | 0 | u128 { 0x547eb47b7282ee9cULL, 0x8e938662882af53eULL }, |
640 | 0 | u128 { 0xe99e619a4f23aa43ULL, 0xb23867fb2a35b28dULL }, |
641 | 0 | u128 { 0x6405fa00e2ec94d4ULL, 0xdec681f9f4c31f31ULL }, |
642 | 0 | u128 { 0xde83bc408dd3dd04ULL, 0x8b3c113c38f9f37eULL }, |
643 | 0 | u128 { 0x9624ab50b148d445ULL, 0xae0b158b4738705eULL }, |
644 | 0 | u128 { 0x3badd624dd9b0957ULL, 0xd98ddaee19068c76ULL }, |
645 | 0 | u128 { 0xe54ca5d70a80e5d6ULL, 0x87f8a8d4cfa417c9ULL }, |
646 | 0 | u128 { 0x5e9fcf4ccd211f4cULL, 0xa9f6d30a038d1dbcULL }, |
647 | 0 | u128 { 0x7647c3200069671fULL, 0xd47487cc8470652bULL }, |
648 | 0 | u128 { 0x29ecd9f40041e073ULL, 0x84c8d4dfd2c63f3bULL }, |
649 | 0 | u128 { 0xf468107100525890ULL, 0xa5fb0a17c777cf09ULL }, |
650 | 0 | u128 { 0x7182148d4066eeb4ULL, 0xcf79cc9db955c2ccULL }, |
651 | 0 | u128 { 0xc6f14cd848405530ULL, 0x81ac1fe293d599bfULL }, |
652 | 0 | u128 { 0xb8ada00e5a506a7cULL, 0xa21727db38cb002fULL }, |
653 | 0 | u128 { 0xa6d90811f0e4851cULL, 0xca9cf1d206fdc03bULL }, |
654 | 0 | u128 { 0x908f4a166d1da663ULL, 0xfd442e4688bd304aULL }, |
655 | 0 | u128 { 0x9a598e4e043287feULL, 0x9e4a9cec15763e2eULL }, |
656 | 0 | u128 { 0x40eff1e1853f29fdULL, 0xc5dd44271ad3cdbaULL }, |
657 | 0 | u128 { 0xd12bee59e68ef47cULL, 0xf7549530e188c128ULL }, |
658 | 0 | u128 { 0x82bb74f8301958ceULL, 0x9a94dd3e8cf578b9ULL }, |
659 | 0 | u128 { 0xe36a52363c1faf01ULL, 0xc13a148e3032d6e7ULL }, |
660 | 0 | u128 { 0xdc44e6c3cb279ac1ULL, 0xf18899b1bc3f8ca1ULL }, |
661 | 0 | u128 { 0x29ab103a5ef8c0b9ULL, 0x96f5600f15a7b7e5ULL }, |
662 | 0 | u128 { 0x7415d448f6b6f0e7ULL, 0xbcb2b812db11a5deULL }, |
663 | 0 | u128 { 0x111b495b3464ad21ULL, 0xebdf661791d60f56ULL }, |
664 | 0 | u128 { 0xcab10dd900beec34ULL, 0x936b9fcebb25c995ULL }, |
665 | 0 | u128 { 0x3d5d514f40eea742ULL, 0xb84687c269ef3bfbULL }, |
666 | 0 | u128 { 0xcb4a5a3112a5112ULL, 0xe65829b3046b0afaULL }, |
667 | 0 | u128 { 0x47f0e785eaba72abULL, 0x8ff71a0fe2c2e6dcULL }, |
668 | 0 | u128 { 0x59ed216765690f56ULL, 0xb3f4e093db73a093ULL }, |
669 | 0 | u128 { 0x306869c13ec3532cULL, 0xe0f218b8d25088b8ULL }, |
670 | 0 | u128 { 0x1e414218c73a13fbULL, 0x8c974f7383725573ULL }, |
671 | 0 | u128 { 0xe5d1929ef90898faULL, 0xafbd2350644eeacfULL }, |
672 | 0 | u128 { 0xdf45f746b74abf39ULL, 0xdbac6c247d62a583ULL }, |
673 | 0 | u128 { 0x6b8bba8c328eb783ULL, 0x894bc396ce5da772ULL }, |
674 | 0 | u128 { 0x66ea92f3f326564ULL, 0xab9eb47c81f5114fULL }, |
675 | 0 | u128 { 0xc80a537b0efefebdULL, 0xd686619ba27255a2ULL }, |
676 | 0 | u128 { 0xbd06742ce95f5f36ULL, 0x8613fd0145877585ULL }, |
677 | 0 | u128 { 0x2c48113823b73704ULL, 0xa798fc4196e952e7ULL }, |
678 | 0 | u128 { 0xf75a15862ca504c5ULL, 0xd17f3b51fca3a7a0ULL }, |
679 | 0 | u128 { 0x9a984d73dbe722fbULL, 0x82ef85133de648c4ULL }, |
680 | 0 | u128 { 0xc13e60d0d2e0ebbaULL, 0xa3ab66580d5fdaf5ULL }, |
681 | 0 | u128 { 0x318df905079926a8ULL, 0xcc963fee10b7d1b3ULL }, |
682 | 0 | u128 { 0xfdf17746497f7052ULL, 0xffbbcfe994e5c61fULL }, |
683 | 0 | u128 { 0xfeb6ea8bedefa633ULL, 0x9fd561f1fd0f9bd3ULL }, |
684 | 0 | u128 { 0xfe64a52ee96b8fc0ULL, 0xc7caba6e7c5382c8ULL }, |
685 | 0 | u128 { 0x3dfdce7aa3c673b0ULL, 0xf9bd690a1b68637bULL }, |
686 | 0 | u128 { 0x6bea10ca65c084eULL, 0x9c1661a651213e2dULL }, |
687 | 0 | u128 { 0x486e494fcff30a62ULL, 0xc31bfa0fe5698db8ULL }, |
688 | 0 | u128 { 0x5a89dba3c3efccfaULL, 0xf3e2f893dec3f126ULL }, |
689 | 0 | u128 { 0xf89629465a75e01cULL, 0x986ddb5c6b3a76b7ULL }, |
690 | 0 | u128 { 0xf6bbb397f1135823ULL, 0xbe89523386091465ULL }, |
691 | 0 | u128 { 0x746aa07ded582e2cULL, 0xee2ba6c0678b597fULL }, |
692 | 0 | u128 { 0xa8c2a44eb4571cdcULL, 0x94db483840b717efULL }, |
693 | 0 | u128 { 0x92f34d62616ce413ULL, 0xba121a4650e4ddebULL }, |
694 | 0 | u128 { 0x77b020baf9c81d17ULL, 0xe896a0d7e51e1566ULL }, |
695 | 0 | u128 { 0xace1474dc1d122eULL, 0x915e2486ef32cd60ULL }, |
696 | 0 | u128 { 0xd819992132456baULL, 0xb5b5ada8aaff80b8ULL }, |
697 | 0 | u128 { 0x10e1fff697ed6c69ULL, 0xe3231912d5bf60e6ULL }, |
698 | 0 | u128 { 0xca8d3ffa1ef463c1ULL, 0x8df5efabc5979c8fULL }, |
699 | 0 | u128 { 0xbd308ff8a6b17cb2ULL, 0xb1736b96b6fd83b3ULL }, |
700 | 0 | u128 { 0xac7cb3f6d05ddbdeULL, 0xddd0467c64bce4a0ULL }, |
701 | 0 | u128 { 0x6bcdf07a423aa96bULL, 0x8aa22c0dbef60ee4ULL }, |
702 | 0 | u128 { 0x86c16c98d2c953c6ULL, 0xad4ab7112eb3929dULL }, |
703 | 0 | u128 { 0xe871c7bf077ba8b7ULL, 0xd89d64d57a607744ULL }, |
704 | 0 | u128 { 0x11471cd764ad4972ULL, 0x87625f056c7c4a8bULL }, |
705 | 0 | u128 { 0xd598e40d3dd89bcfULL, 0xa93af6c6c79b5d2dULL }, |
706 | 0 | u128 { 0x4aff1d108d4ec2c3ULL, 0xd389b47879823479ULL }, |
707 | 0 | u128 { 0xcedf722a585139baULL, 0x843610cb4bf160cbULL }, |
708 | 0 | u128 { 0xc2974eb4ee658828ULL, 0xa54394fe1eedb8feULL }, |
709 | 0 | u128 { 0x733d226229feea32ULL, 0xce947a3da6a9273eULL }, |
710 | 0 | u128 { 0x806357d5a3f525fULL, 0x811ccc668829b887ULL }, |
711 | 0 | u128 { 0xca07c2dcb0cf26f7ULL, 0xa163ff802a3426a8ULL }, |
712 | 0 | u128 { 0xfc89b393dd02f0b5ULL, 0xc9bcff6034c13052ULL }, |
713 | 0 | u128 { 0xbbac2078d443ace2ULL, 0xfc2c3f3841f17c67ULL }, |
714 | 0 | u128 { 0xd54b944b84aa4c0dULL, 0x9d9ba7832936edc0ULL }, |
715 | 0 | u128 { 0xa9e795e65d4df11ULL, 0xc5029163f384a931ULL }, |
716 | 0 | u128 { 0x4d4617b5ff4a16d5ULL, 0xf64335bcf065d37dULL }, |
717 | 0 | u128 { 0x504bced1bf8e4e45ULL, 0x99ea0196163fa42eULL }, |
718 | 0 | u128 { 0xe45ec2862f71e1d6ULL, 0xc06481fb9bcf8d39ULL }, |
719 | 0 | u128 { 0x5d767327bb4e5a4cULL, 0xf07da27a82c37088ULL }, |
720 | 0 | u128 { 0x3a6a07f8d510f86fULL, 0x964e858c91ba2655ULL }, |
721 | 0 | u128 { 0x890489f70a55368bULL, 0xbbe226efb628afeaULL }, |
722 | 0 | u128 { 0x2b45ac74ccea842eULL, 0xeadab0aba3b2dbe5ULL }, |
723 | 0 | u128 { 0x3b0b8bc90012929dULL, 0x92c8ae6b464fc96fULL }, |
724 | 0 | u128 { 0x9ce6ebb40173744ULL, 0xb77ada0617e3bbcbULL }, |
725 | 0 | u128 { 0xcc420a6a101d0515ULL, 0xe55990879ddcaabdULL }, |
726 | 0 | u128 { 0x9fa946824a12232dULL, 0x8f57fa54c2a9eab6ULL }, |
727 | 0 | u128 { 0x47939822dc96abf9ULL, 0xb32df8e9f3546564ULL }, |
728 | 0 | u128 { 0x59787e2b93bc56f7ULL, 0xdff9772470297ebdULL }, |
729 | 0 | u128 { 0x57eb4edb3c55b65aULL, 0x8bfbea76c619ef36ULL }, |
730 | 0 | u128 { 0xede622920b6b23f1ULL, 0xaefae51477a06b03ULL }, |
731 | 0 | u128 { 0xe95fab368e45ecedULL, 0xdab99e59958885c4ULL }, |
732 | 0 | u128 { 0x11dbcb0218ebb414ULL, 0x88b402f7fd75539bULL }, |
733 | 0 | u128 { 0xd652bdc29f26a119ULL, 0xaae103b5fcd2a881ULL }, |
734 | 0 | u128 { 0x4be76d3346f0495fULL, 0xd59944a37c0752a2ULL }, |
735 | 0 | u128 { 0x6f70a4400c562ddbULL, 0x857fcae62d8493a5ULL }, |
736 | 0 | u128 { 0xcb4ccd500f6bb952ULL, 0xa6dfbd9fb8e5b88eULL }, |
737 | 0 | u128 { 0x7e2000a41346a7a7ULL, 0xd097ad07a71f26b2ULL }, |
738 | 0 | u128 { 0x8ed400668c0c28c8ULL, 0x825ecc24c873782fULL }, |
739 | 0 | u128 { 0x728900802f0f32faULL, 0xa2f67f2dfa90563bULL }, |
740 | 0 | u128 { 0x4f2b40a03ad2ffb9ULL, 0xcbb41ef979346bcaULL }, |
741 | 0 | u128 { 0xe2f610c84987bfa8ULL, 0xfea126b7d78186bcULL }, |
742 | 0 | u128 { 0xdd9ca7d2df4d7c9ULL, 0x9f24b832e6b0f436ULL }, |
743 | 0 | u128 { 0x91503d1c79720dbbULL, 0xc6ede63fa05d3143ULL }, |
744 | 0 | u128 { 0x75a44c6397ce912aULL, 0xf8a95fcf88747d94ULL }, |
745 | 0 | u128 { 0xc986afbe3ee11abaULL, 0x9b69dbe1b548ce7cULL }, |
746 | 0 | u128 { 0xfbe85badce996168ULL, 0xc24452da229b021bULL }, |
747 | 0 | u128 { 0xfae27299423fb9c3ULL, 0xf2d56790ab41c2a2ULL }, |
748 | 0 | u128 { 0xdccd879fc967d41aULL, 0x97c560ba6b0919a5ULL }, |
749 | 0 | u128 { 0x5400e987bbc1c920ULL, 0xbdb6b8e905cb600fULL }, |
750 | 0 | u128 { 0x290123e9aab23b68ULL, 0xed246723473e3813ULL }, |
751 | 0 | u128 { 0xf9a0b6720aaf6521ULL, 0x9436c0760c86e30bULL }, |
752 | 0 | u128 { 0xf808e40e8d5b3e69ULL, 0xb94470938fa89bceULL }, |
753 | 0 | u128 { 0xb60b1d1230b20e04ULL, 0xe7958cb87392c2c2ULL }, |
754 | 0 | u128 { 0xb1c6f22b5e6f48c2ULL, 0x90bd77f3483bb9b9ULL }, |
755 | 0 | u128 { 0x1e38aeb6360b1af3ULL, 0xb4ecd5f01a4aa828ULL }, |
756 | 0 | u128 { 0x25c6da63c38de1b0ULL, 0xe2280b6c20dd5232ULL }, |
757 | 0 | u128 { 0x579c487e5a38ad0eULL, 0x8d590723948a535fULL }, |
758 | 0 | u128 { 0x2d835a9df0c6d851ULL, 0xb0af48ec79ace837ULL }, |
759 | 0 | u128 { 0xf8e431456cf88e65ULL, 0xdcdb1b2798182244ULL }, |
760 | 0 | u128 { 0x1b8e9ecb641b58ffULL, 0x8a08f0f8bf0f156bULL }, |
761 | 0 | u128 { 0xe272467e3d222f3fULL, 0xac8b2d36eed2dac5ULL }, |
762 | 0 | u128 { 0x5b0ed81dcc6abb0fULL, 0xd7adf884aa879177ULL }, |
763 | 0 | u128 { 0x98e947129fc2b4e9ULL, 0x86ccbb52ea94baeaULL }, |
764 | 0 | u128 { 0x3f2398d747b36224ULL, 0xa87fea27a539e9a5ULL }, |
765 | 0 | u128 { 0x8eec7f0d19a03aadULL, 0xd29fe4b18e88640eULL }, |
766 | 0 | u128 { 0x1953cf68300424acULL, 0x83a3eeeef9153e89ULL }, |
767 | 0 | u128 { 0x5fa8c3423c052dd7ULL, 0xa48ceaaab75a8e2bULL }, |
768 | 0 | u128 { 0x3792f412cb06794dULL, 0xcdb02555653131b6ULL }, |
769 | 0 | u128 { 0xe2bbd88bbee40bd0ULL, 0x808e17555f3ebf11ULL }, |
770 | 0 | u128 { 0x5b6aceaeae9d0ec4ULL, 0xa0b19d2ab70e6ed6ULL }, |
771 | 0 | u128 { 0xf245825a5a445275ULL, 0xc8de047564d20a8bULL }, |
772 | 0 | u128 { 0xeed6e2f0f0d56712ULL, 0xfb158592be068d2eULL }, |
773 | 0 | u128 { 0x55464dd69685606bULL, 0x9ced737bb6c4183dULL }, |
774 | 0 | u128 { 0xaa97e14c3c26b886ULL, 0xc428d05aa4751e4cULL }, |
775 | 0 | u128 { 0xd53dd99f4b3066a8ULL, 0xf53304714d9265dfULL }, |
776 | 0 | u128 { 0xe546a8038efe4029ULL, 0x993fe2c6d07b7fabULL }, |
777 | 0 | u128 { 0xde98520472bdd033ULL, 0xbf8fdb78849a5f96ULL }, |
778 | 0 | u128 { 0x963e66858f6d4440ULL, 0xef73d256a5c0f77cULL }, |
779 | 0 | u128 { 0xdde7001379a44aa8ULL, 0x95a8637627989aadULL }, |
780 | 0 | u128 { 0x5560c018580d5d52ULL, 0xbb127c53b17ec159ULL }, |
781 | 0 | u128 { 0xaab8f01e6e10b4a6ULL, 0xe9d71b689dde71afULL }, |
782 | 0 | u128 { 0xcab3961304ca70e8ULL, 0x9226712162ab070dULL }, |
783 | 0 | u128 { 0x3d607b97c5fd0d22ULL, 0xb6b00d69bb55c8d1ULL }, |
784 | 0 | u128 { 0x8cb89a7db77c506aULL, 0xe45c10c42a2b3b05ULL }, |
785 | 0 | u128 { 0x77f3608e92adb242ULL, 0x8eb98a7a9a5b04e3ULL }, |
786 | 0 | u128 { 0x55f038b237591ed3ULL, 0xb267ed1940f1c61cULL }, |
787 | 0 | u128 { 0x6b6c46dec52f6688ULL, 0xdf01e85f912e37a3ULL }, |
788 | 0 | u128 { 0x2323ac4b3b3da015ULL, 0x8b61313bbabce2c6ULL }, |
789 | 0 | u128 { 0xabec975e0a0d081aULL, 0xae397d8aa96c1b77ULL }, |
790 | 0 | u128 { 0x96e7bd358c904a21ULL, 0xd9c7dced53c72255ULL }, |
791 | 0 | u128 { 0x7e50d64177da2e54ULL, 0x881cea14545c7575ULL }, |
792 | 0 | u128 { 0xdde50bd1d5d0b9e9ULL, 0xaa242499697392d2ULL }, |
793 | 0 | u128 { 0x955e4ec64b44e864ULL, 0xd4ad2dbfc3d07787ULL }, |
794 | 0 | u128 { 0xbd5af13bef0b113eULL, 0x84ec3c97da624ab4ULL }, |
795 | 0 | u128 { 0xecb1ad8aeacdd58eULL, 0xa6274bbdd0fadd61ULL }, |
796 | 0 | u128 { 0x67de18eda5814af2ULL, 0xcfb11ead453994baULL }, |
797 | 0 | u128 { 0x80eacf948770ced7ULL, 0x81ceb32c4b43fcf4ULL }, |
798 | 0 | u128 { 0xa1258379a94d028dULL, 0xa2425ff75e14fc31ULL }, |
799 | 0 | u128 { 0x96ee45813a04330ULL, 0xcad2f7f5359a3b3eULL }, |
800 | 0 | u128 { 0x8bca9d6e188853fcULL, 0xfd87b5f28300ca0dULL }, |
801 | 0 | u128 { 0x775ea264cf55347eULL, 0x9e74d1b791e07e48ULL }, |
802 | 0 | u128 { 0x95364afe032a819eULL, 0xc612062576589ddaULL }, |
803 | 0 | u128 { 0x3a83ddbd83f52205ULL, 0xf79687aed3eec551ULL }, |
804 | 0 | u128 { 0xc4926a9672793543ULL, 0x9abe14cd44753b52ULL }, |
805 | 0 | u128 { 0x75b7053c0f178294ULL, 0xc16d9a0095928a27ULL }, |
806 | 0 | u128 { 0x5324c68b12dd6339ULL, 0xf1c90080baf72cb1ULL }, |
807 | 0 | u128 { 0xd3f6fc16ebca5e04ULL, 0x971da05074da7beeULL }, |
808 | 0 | u128 { 0x88f4bb1ca6bcf585ULL, 0xbce5086492111aeaULL }, |
809 | 0 | u128 { 0x2b31e9e3d06c32e6ULL, 0xec1e4a7db69561a5ULL }, |
810 | 0 | u128 { 0x3aff322e62439fd0ULL, 0x9392ee8e921d5d07ULL }, |
811 | 0 | u128 { 0x9befeb9fad487c3ULL, 0xb877aa3236a4b449ULL }, |
812 | 0 | u128 { 0x4c2ebe687989a9b4ULL, 0xe69594bec44de15bULL }, |
813 | 0 | u128 { 0xf9d37014bf60a11ULL, 0x901d7cf73ab0acd9ULL }, |
814 | 0 | u128 { 0x538484c19ef38c95ULL, 0xb424dc35095cd80fULL }, |
815 | 0 | u128 { 0x2865a5f206b06fbaULL, 0xe12e13424bb40e13ULL }, |
816 | 0 | u128 { 0xf93f87b7442e45d4ULL, 0x8cbccc096f5088cbULL }, |
817 | 0 | u128 { 0xf78f69a51539d749ULL, 0xafebff0bcb24aafeULL }, |
818 | 0 | u128 { 0xb573440e5a884d1cULL, 0xdbe6fecebdedd5beULL }, |
819 | 0 | u128 { 0x31680a88f8953031ULL, 0x89705f4136b4a597ULL }, |
820 | 0 | u128 { 0xfdc20d2b36ba7c3eULL, 0xabcc77118461cefcULL }, |
821 | 0 | u128 { 0x3d32907604691b4dULL, 0xd6bf94d5e57a42bcULL }, |
822 | 0 | u128 { 0xa63f9a49c2c1b110ULL, 0x8637bd05af6c69b5ULL }, |
823 | 0 | u128 { 0xfcf80dc33721d54ULL, 0xa7c5ac471b478423ULL }, |
824 | 0 | u128 { 0xd3c36113404ea4a9ULL, 0xd1b71758e219652bULL }, |
825 | 0 | u128 { 0x645a1cac083126eaULL, 0x83126e978d4fdf3bULL }, |
826 | 0 | u128 { 0x3d70a3d70a3d70a4ULL, 0xa3d70a3d70a3d70aULL }, |
827 | 0 | u128 { 0xcccccccccccccccdULL, 0xccccccccccccccccULL }, |
828 | 0 | compute_power_of_five(0), |
829 | 0 | u128 { 0x0ULL, 0xa000000000000000ULL }, |
830 | 0 | u128 { 0x0ULL, 0xc800000000000000ULL }, |
831 | 0 | u128 { 0x0ULL, 0xfa00000000000000ULL }, |
832 | 0 | u128 { 0x0ULL, 0x9c40000000000000ULL }, |
833 | 0 | u128 { 0x0ULL, 0xc350000000000000ULL }, |
834 | 0 | u128 { 0x0ULL, 0xf424000000000000ULL }, |
835 | 0 | u128 { 0x0ULL, 0x9896800000000000ULL }, |
836 | 0 | u128 { 0x0ULL, 0xbebc200000000000ULL }, |
837 | 0 | u128 { 0x0ULL, 0xee6b280000000000ULL }, |
838 | 0 | u128 { 0x0ULL, 0x9502f90000000000ULL }, |
839 | 0 | u128 { 0x0ULL, 0xba43b74000000000ULL }, |
840 | 0 | u128 { 0x0ULL, 0xe8d4a51000000000ULL }, |
841 | 0 | u128 { 0x0ULL, 0x9184e72a00000000ULL }, |
842 | 0 | u128 { 0x0ULL, 0xb5e620f480000000ULL }, |
843 | 0 | u128 { 0x0ULL, 0xe35fa931a0000000ULL }, |
844 | 0 | u128 { 0x0ULL, 0x8e1bc9bf04000000ULL }, |
845 | 0 | u128 { 0x0ULL, 0xb1a2bc2ec5000000ULL }, |
846 | 0 | u128 { 0x0ULL, 0xde0b6b3a76400000ULL }, |
847 | 0 | u128 { 0x0ULL, 0x8ac7230489e80000ULL }, |
848 | 0 | u128 { 0x0ULL, 0xad78ebc5ac620000ULL }, |
849 | 0 | u128 { 0x0ULL, 0xd8d726b7177a8000ULL }, |
850 | 0 | u128 { 0x0ULL, 0x878678326eac9000ULL }, |
851 | 0 | u128 { 0x0ULL, 0xa968163f0a57b400ULL }, |
852 | 0 | u128 { 0x0ULL, 0xd3c21bcecceda100ULL }, |
853 | 0 | u128 { 0x0ULL, 0x84595161401484a0ULL }, |
854 | 0 | u128 { 0x0ULL, 0xa56fa5b99019a5c8ULL }, |
855 | 0 | u128 { 0x0ULL, 0xcecb8f27f4200f3aULL }, |
856 | 0 | u128 { 0x4000000000000000ULL, 0x813f3978f8940984ULL }, |
857 | 0 | u128 { 0x5000000000000000ULL, 0xa18f07d736b90be5ULL }, |
858 | 0 | u128 { 0xa400000000000000ULL, 0xc9f2c9cd04674edeULL }, |
859 | 0 | u128 { 0x4d00000000000000ULL, 0xfc6f7c4045812296ULL }, |
860 | 0 | u128 { 0xf020000000000000ULL, 0x9dc5ada82b70b59dULL }, |
861 | 0 | u128 { 0x6c28000000000000ULL, 0xc5371912364ce305ULL }, |
862 | 0 | u128 { 0xc732000000000000ULL, 0xf684df56c3e01bc6ULL }, |
863 | 0 | u128 { 0x3c7f400000000000ULL, 0x9a130b963a6c115cULL }, |
864 | 0 | u128 { 0x4b9f100000000000ULL, 0xc097ce7bc90715b3ULL }, |
865 | 0 | u128 { 0x1e86d40000000000ULL, 0xf0bdc21abb48db20ULL }, |
866 | 0 | u128 { 0x1314448000000000ULL, 0x96769950b50d88f4ULL }, |
867 | 0 | u128 { 0x17d955a000000000ULL, 0xbc143fa4e250eb31ULL }, |
868 | 0 | u128 { 0x5dcfab0800000000ULL, 0xeb194f8e1ae525fdULL }, |
869 | 0 | u128 { 0x5aa1cae500000000ULL, 0x92efd1b8d0cf37beULL }, |
870 | 0 | u128 { 0xf14a3d9e40000000ULL, 0xb7abc627050305adULL }, |
871 | 0 | u128 { 0x6d9ccd05d0000000ULL, 0xe596b7b0c643c719ULL }, |
872 | 0 | u128 { 0xe4820023a2000000ULL, 0x8f7e32ce7bea5c6fULL }, |
873 | 0 | u128 { 0xdda2802c8a800000ULL, 0xb35dbf821ae4f38bULL }, |
874 | 0 | u128 { 0xd50b2037ad200000ULL, 0xe0352f62a19e306eULL }, |
875 | 0 | u128 { 0x4526f422cc340000ULL, 0x8c213d9da502de45ULL }, |
876 | 0 | u128 { 0x9670b12b7f410000ULL, 0xaf298d050e4395d6ULL }, |
877 | 0 | u128 { 0x3c0cdd765f114000ULL, 0xdaf3f04651d47b4cULL }, |
878 | 0 | u128 { 0xa5880a69fb6ac800ULL, 0x88d8762bf324cd0fULL }, |
879 | 0 | u128 { 0x8eea0d047a457a00ULL, 0xab0e93b6efee0053ULL }, |
880 | 0 | u128 { 0x72a4904598d6d880ULL, 0xd5d238a4abe98068ULL }, |
881 | 0 | u128 { 0x47a6da2b7f864750ULL, 0x85a36366eb71f041ULL }, |
882 | 0 | u128 { 0x999090b65f67d924ULL, 0xa70c3c40a64e6c51ULL }, |
883 | 0 | u128 { 0xfff4b4e3f741cf6dULL, 0xd0cf4b50cfe20765ULL }, |
884 | 0 | u128 { 0xbff8f10e7a8921a4ULL, 0x82818f1281ed449fULL }, |
885 | 0 | u128 { 0xaff72d52192b6a0dULL, 0xa321f2d7226895c7ULL }, |
886 | 0 | u128 { 0x9bf4f8a69f764490ULL, 0xcbea6f8ceb02bb39ULL }, |
887 | 0 | u128 { 0x2f236d04753d5b4ULL, 0xfee50b7025c36a08ULL }, |
888 | 0 | u128 { 0x1d762422c946590ULL, 0x9f4f2726179a2245ULL }, |
889 | 0 | u128 { 0x424d3ad2b7b97ef5ULL, 0xc722f0ef9d80aad6ULL }, |
890 | 0 | u128 { 0xd2e0898765a7deb2ULL, 0xf8ebad2b84e0d58bULL }, |
891 | 0 | u128 { 0x63cc55f49f88eb2fULL, 0x9b934c3b330c8577ULL }, |
892 | 0 | u128 { 0x3cbf6b71c76b25fbULL, 0xc2781f49ffcfa6d5ULL }, |
893 | 0 | u128 { 0x8bef464e3945ef7aULL, 0xf316271c7fc3908aULL }, |
894 | 0 | u128 { 0x97758bf0e3cbb5acULL, 0x97edd871cfda3a56ULL }, |
895 | 0 | u128 { 0x3d52eeed1cbea317ULL, 0xbde94e8e43d0c8ecULL }, |
896 | 0 | u128 { 0x4ca7aaa863ee4bddULL, 0xed63a231d4c4fb27ULL }, |
897 | 0 | u128 { 0x8fe8caa93e74ef6aULL, 0x945e455f24fb1cf8ULL }, |
898 | 0 | u128 { 0xb3e2fd538e122b44ULL, 0xb975d6b6ee39e436ULL }, |
899 | 0 | u128 { 0x60dbbca87196b616ULL, 0xe7d34c64a9c85d44ULL }, |
900 | 0 | u128 { 0xbc8955e946fe31cdULL, 0x90e40fbeea1d3a4aULL }, |
901 | 0 | u128 { 0x6babab6398bdbe41ULL, 0xb51d13aea4a488ddULL }, |
902 | 0 | u128 { 0xc696963c7eed2dd1ULL, 0xe264589a4dcdab14ULL }, |
903 | 0 | u128 { 0xfc1e1de5cf543ca2ULL, 0x8d7eb76070a08aecULL }, |
904 | 0 | u128 { 0x3b25a55f43294bcbULL, 0xb0de65388cc8ada8ULL }, |
905 | 0 | u128 { 0x49ef0eb713f39ebeULL, 0xdd15fe86affad912ULL }, |
906 | 0 | u128 { 0x6e3569326c784337ULL, 0x8a2dbf142dfcc7abULL }, |
907 | 0 | u128 { 0x49c2c37f07965404ULL, 0xacb92ed9397bf996ULL }, |
908 | 0 | u128 { 0xdc33745ec97be906ULL, 0xd7e77a8f87daf7fbULL }, |
909 | 0 | u128 { 0x69a028bb3ded71a3ULL, 0x86f0ac99b4e8dafdULL }, |
910 | 0 | u128 { 0xc40832ea0d68ce0cULL, 0xa8acd7c0222311bcULL }, |
911 | 0 | u128 { 0xf50a3fa490c30190ULL, 0xd2d80db02aabd62bULL }, |
912 | 0 | u128 { 0x792667c6da79e0faULL, 0x83c7088e1aab65dbULL }, |
913 | 0 | u128 { 0x577001b891185938ULL, 0xa4b8cab1a1563f52ULL }, |
914 | 0 | u128 { 0xed4c0226b55e6f86ULL, 0xcde6fd5e09abcf26ULL }, |
915 | 0 | u128 { 0x544f8158315b05b4ULL, 0x80b05e5ac60b6178ULL }, |
916 | 0 | u128 { 0x696361ae3db1c721ULL, 0xa0dc75f1778e39d6ULL }, |
917 | 0 | u128 { 0x3bc3a19cd1e38e9ULL, 0xc913936dd571c84cULL }, |
918 | 0 | u128 { 0x4ab48a04065c723ULL, 0xfb5878494ace3a5fULL }, |
919 | 0 | u128 { 0x62eb0d64283f9c76ULL, 0x9d174b2dcec0e47bULL }, |
920 | 0 | u128 { 0x3ba5d0bd324f8394ULL, 0xc45d1df942711d9aULL }, |
921 | 0 | u128 { 0xca8f44ec7ee36479ULL, 0xf5746577930d6500ULL }, |
922 | 0 | u128 { 0x7e998b13cf4e1ecbULL, 0x9968bf6abbe85f20ULL }, |
923 | 0 | u128 { 0x9e3fedd8c321a67eULL, 0xbfc2ef456ae276e8ULL }, |
924 | 0 | u128 { 0xc5cfe94ef3ea101eULL, 0xefb3ab16c59b14a2ULL }, |
925 | 0 | u128 { 0xbba1f1d158724a12ULL, 0x95d04aee3b80ece5ULL }, |
926 | 0 | u128 { 0x2a8a6e45ae8edc97ULL, 0xbb445da9ca61281fULL }, |
927 | 0 | u128 { 0xf52d09d71a3293bdULL, 0xea1575143cf97226ULL }, |
928 | 0 | u128 { 0x593c2626705f9c56ULL, 0x924d692ca61be758ULL }, |
929 | 0 | u128 { 0x6f8b2fb00c77836cULL, 0xb6e0c377cfa2e12eULL }, |
930 | 0 | u128 { 0xb6dfb9c0f956447ULL, 0xe498f455c38b997aULL }, |
931 | 0 | u128 { 0x4724bd4189bd5eacULL, 0x8edf98b59a373fecULL }, |
932 | 0 | u128 { 0x58edec91ec2cb657ULL, 0xb2977ee300c50fe7ULL }, |
933 | 0 | u128 { 0x2f2967b66737e3edULL, 0xdf3d5e9bc0f653e1ULL }, |
934 | 0 | u128 { 0xbd79e0d20082ee74ULL, 0x8b865b215899f46cULL }, |
935 | 0 | u128 { 0xecd8590680a3aa11ULL, 0xae67f1e9aec07187ULL }, |
936 | 0 | u128 { 0xe80e6f4820cc9495ULL, 0xda01ee641a708de9ULL }, |
937 | 0 | u128 { 0x3109058d147fdcddULL, 0x884134fe908658b2ULL }, |
938 | 0 | u128 { 0xbd4b46f0599fd415ULL, 0xaa51823e34a7eedeULL }, |
939 | 0 | u128 { 0x6c9e18ac7007c91aULL, 0xd4e5e2cdc1d1ea96ULL }, |
940 | 0 | u128 { 0x3e2cf6bc604ddb0ULL, 0x850fadc09923329eULL }, |
941 | 0 | u128 { 0x84db8346b786151cULL, 0xa6539930bf6bff45ULL }, |
942 | 0 | u128 { 0xe612641865679a63ULL, 0xcfe87f7cef46ff16ULL }, |
943 | 0 | u128 { 0x4fcb7e8f3f60c07eULL, 0x81f14fae158c5f6eULL }, |
944 | 0 | u128 { 0xe3be5e330f38f09dULL, 0xa26da3999aef7749ULL }, |
945 | 0 | u128 { 0x5cadf5bfd3072cc5ULL, 0xcb090c8001ab551cULL }, |
946 | 0 | u128 { 0x73d9732fc7c8f7f6ULL, 0xfdcb4fa002162a63ULL }, |
947 | 0 | u128 { 0x2867e7fddcdd9afaULL, 0x9e9f11c4014dda7eULL }, |
948 | 0 | u128 { 0xb281e1fd541501b8ULL, 0xc646d63501a1511dULL }, |
949 | 0 | u128 { 0x1f225a7ca91a4226ULL, 0xf7d88bc24209a565ULL }, |
950 | 0 | u128 { 0x3375788de9b06958ULL, 0x9ae757596946075fULL }, |
951 | 0 | u128 { 0x52d6b1641c83aeULL, 0xc1a12d2fc3978937ULL }, |
952 | 0 | u128 { 0xc0678c5dbd23a49aULL, 0xf209787bb47d6b84ULL }, |
953 | 0 | u128 { 0xf840b7ba963646e0ULL, 0x9745eb4d50ce6332ULL }, |
954 | 0 | u128 { 0xb650e5a93bc3d898ULL, 0xbd176620a501fbffULL }, |
955 | 0 | u128 { 0xa3e51f138ab4cebeULL, 0xec5d3fa8ce427affULL }, |
956 | 0 | u128 { 0xc66f336c36b10137ULL, 0x93ba47c980e98cdfULL }, |
957 | 0 | u128 { 0xb80b0047445d4184ULL, 0xb8a8d9bbe123f017ULL }, |
958 | 0 | u128 { 0xa60dc059157491e5ULL, 0xe6d3102ad96cec1dULL }, |
959 | 0 | u128 { 0x87c89837ad68db2fULL, 0x9043ea1ac7e41392ULL }, |
960 | 0 | u128 { 0x29babe4598c311fbULL, 0xb454e4a179dd1877ULL }, |
961 | 0 | u128 { 0xf4296dd6fef3d67aULL, 0xe16a1dc9d8545e94ULL }, |
962 | 0 | u128 { 0x1899e4a65f58660cULL, 0x8ce2529e2734bb1dULL }, |
963 | 0 | u128 { 0x5ec05dcff72e7f8fULL, 0xb01ae745b101e9e4ULL }, |
964 | 0 | u128 { 0x76707543f4fa1f73ULL, 0xdc21a1171d42645dULL }, |
965 | 0 | u128 { 0x6a06494a791c53a8ULL, 0x899504ae72497ebaULL }, |
966 | 0 | u128 { 0x487db9d17636892ULL, 0xabfa45da0edbde69ULL }, |
967 | 0 | u128 { 0x45a9d2845d3c42b6ULL, 0xd6f8d7509292d603ULL }, |
968 | 0 | u128 { 0xb8a2392ba45a9b2ULL, 0x865b86925b9bc5c2ULL }, |
969 | 0 | u128 { 0x8e6cac7768d7141eULL, 0xa7f26836f282b732ULL }, |
970 | 0 | u128 { 0x3207d795430cd926ULL, 0xd1ef0244af2364ffULL }, |
971 | 0 | u128 { 0x7f44e6bd49e807b8ULL, 0x8335616aed761f1fULL }, |
972 | 0 | u128 { 0x5f16206c9c6209a6ULL, 0xa402b9c5a8d3a6e7ULL }, |
973 | 0 | u128 { 0x36dba887c37a8c0fULL, 0xcd036837130890a1ULL }, |
974 | 0 | u128 { 0xc2494954da2c9789ULL, 0x802221226be55a64ULL }, |
975 | 0 | u128 { 0xf2db9baa10b7bd6cULL, 0xa02aa96b06deb0fdULL }, |
976 | 0 | u128 { 0x6f92829494e5acc7ULL, 0xc83553c5c8965d3dULL }, |
977 | 0 | u128 { 0xcb772339ba1f17f9ULL, 0xfa42a8b73abbf48cULL }, |
978 | 0 | u128 { 0xff2a760414536efbULL, 0x9c69a97284b578d7ULL }, |
979 | 0 | u128 { 0xfef5138519684abaULL, 0xc38413cf25e2d70dULL }, |
980 | 0 | u128 { 0x7eb258665fc25d69ULL, 0xf46518c2ef5b8cd1ULL }, |
981 | 0 | u128 { 0xef2f773ffbd97a61ULL, 0x98bf2f79d5993802ULL }, |
982 | 0 | u128 { 0xaafb550ffacfd8faULL, 0xbeeefb584aff8603ULL }, |
983 | 0 | u128 { 0x95ba2a53f983cf38ULL, 0xeeaaba2e5dbf6784ULL }, |
984 | 0 | u128 { 0xdd945a747bf26183ULL, 0x952ab45cfa97a0b2ULL }, |
985 | 0 | u128 { 0x94f971119aeef9e4ULL, 0xba756174393d88dfULL }, |
986 | 0 | u128 { 0x7a37cd5601aab85dULL, 0xe912b9d1478ceb17ULL }, |
987 | 0 | u128 { 0xac62e055c10ab33aULL, 0x91abb422ccb812eeULL }, |
988 | 0 | u128 { 0x577b986b314d6009ULL, 0xb616a12b7fe617aaULL }, |
989 | 0 | u128 { 0xed5a7e85fda0b80bULL, 0xe39c49765fdf9d94ULL }, |
990 | 0 | u128 { 0x14588f13be847307ULL, 0x8e41ade9fbebc27dULL }, |
991 | 0 | u128 { 0x596eb2d8ae258fc8ULL, 0xb1d219647ae6b31cULL }, |
992 | 0 | u128 { 0x6fca5f8ed9aef3bbULL, 0xde469fbd99a05fe3ULL }, |
993 | 0 | u128 { 0x25de7bb9480d5854ULL, 0x8aec23d680043beeULL }, |
994 | 0 | u128 { 0xaf561aa79a10ae6aULL, 0xada72ccc20054ae9ULL }, |
995 | 0 | u128 { 0x1b2ba1518094da04ULL, 0xd910f7ff28069da4ULL }, |
996 | 0 | u128 { 0x90fb44d2f05d0842ULL, 0x87aa9aff79042286ULL }, |
997 | 0 | u128 { 0x353a1607ac744a53ULL, 0xa99541bf57452b28ULL }, |
998 | 0 | u128 { 0x42889b8997915ce8ULL, 0xd3fa922f2d1675f2ULL }, |
999 | 0 | u128 { 0x69956135febada11ULL, 0x847c9b5d7c2e09b7ULL }, |
1000 | 0 | u128 { 0x43fab9837e699095ULL, 0xa59bc234db398c25ULL }, |
1001 | 0 | u128 { 0x94f967e45e03f4bbULL, 0xcf02b2c21207ef2eULL }, |
1002 | 0 | u128 { 0x1d1be0eebac278f5ULL, 0x8161afb94b44f57dULL }, |
1003 | 0 | u128 { 0x6462d92a69731732ULL, 0xa1ba1ba79e1632dcULL }, |
1004 | 0 | u128 { 0x7d7b8f7503cfdcfeULL, 0xca28a291859bbf93ULL }, |
1005 | 0 | u128 { 0x5cda735244c3d43eULL, 0xfcb2cb35e702af78ULL }, |
1006 | 0 | u128 { 0x3a0888136afa64a7ULL, 0x9defbf01b061adabULL }, |
1007 | 0 | u128 { 0x88aaa1845b8fdd0ULL, 0xc56baec21c7a1916ULL }, |
1008 | 0 | u128 { 0x8aad549e57273d45ULL, 0xf6c69a72a3989f5bULL }, |
1009 | 0 | u128 { 0x36ac54e2f678864bULL, 0x9a3c2087a63f6399ULL }, |
1010 | 0 | u128 { 0x84576a1bb416a7ddULL, 0xc0cb28a98fcf3c7fULL }, |
1011 | 0 | u128 { 0x656d44a2a11c51d5ULL, 0xf0fdf2d3f3c30b9fULL }, |
1012 | 0 | u128 { 0x9f644ae5a4b1b325ULL, 0x969eb7c47859e743ULL }, |
1013 | 0 | u128 { 0x873d5d9f0dde1feeULL, 0xbc4665b596706114ULL }, |
1014 | 0 | u128 { 0xa90cb506d155a7eaULL, 0xeb57ff22fc0c7959ULL }, |
1015 | 0 | u128 { 0x9a7f12442d588f2ULL, 0x9316ff75dd87cbd8ULL }, |
1016 | 0 | u128 { 0xc11ed6d538aeb2fULL, 0xb7dcbf5354e9beceULL }, |
1017 | 0 | u128 { 0x8f1668c8a86da5faULL, 0xe5d3ef282a242e81ULL }, |
1018 | 0 | u128 { 0xf96e017d694487bcULL, 0x8fa475791a569d10ULL }, |
1019 | 0 | u128 { 0x37c981dcc395a9acULL, 0xb38d92d760ec4455ULL }, |
1020 | 0 | u128 { 0x85bbe253f47b1417ULL, 0xe070f78d3927556aULL }, |
1021 | 0 | u128 { 0x93956d7478ccec8eULL, 0x8c469ab843b89562ULL }, |
1022 | 0 | u128 { 0x387ac8d1970027b2ULL, 0xaf58416654a6babbULL }, |
1023 | 0 | u128 { 0x6997b05fcc0319eULL, 0xdb2e51bfe9d0696aULL }, |
1024 | 0 | u128 { 0x441fece3bdf81f03ULL, 0x88fcf317f22241e2ULL }, |
1025 | 0 | u128 { 0xd527e81cad7626c3ULL, 0xab3c2fddeeaad25aULL }, |
1026 | 0 | u128 { 0x8a71e223d8d3b074ULL, 0xd60b3bd56a5586f1ULL }, |
1027 | 0 | u128 { 0xf6872d5667844e49ULL, 0x85c7056562757456ULL }, |
1028 | 0 | u128 { 0xb428f8ac016561dbULL, 0xa738c6bebb12d16cULL }, |
1029 | 0 | u128 { 0xe13336d701beba52ULL, 0xd106f86e69d785c7ULL }, |
1030 | 0 | u128 { 0xecc0024661173473ULL, 0x82a45b450226b39cULL }, |
1031 | 0 | u128 { 0x27f002d7f95d0190ULL, 0xa34d721642b06084ULL }, |
1032 | 0 | u128 { 0x31ec038df7b441f4ULL, 0xcc20ce9bd35c78a5ULL }, |
1033 | 0 | u128 { 0x7e67047175a15271ULL, 0xff290242c83396ceULL }, |
1034 | 0 | u128 { 0xf0062c6e984d386ULL, 0x9f79a169bd203e41ULL }, |
1035 | 0 | u128 { 0x52c07b78a3e60868ULL, 0xc75809c42c684dd1ULL }, |
1036 | 0 | u128 { 0xa7709a56ccdf8a82ULL, 0xf92e0c3537826145ULL }, |
1037 | 0 | u128 { 0x88a66076400bb691ULL, 0x9bbcc7a142b17ccbULL }, |
1038 | 0 | u128 { 0x6acff893d00ea435ULL, 0xc2abf989935ddbfeULL }, |
1039 | 0 | u128 { 0x583f6b8c4124d43ULL, 0xf356f7ebf83552feULL }, |
1040 | 0 | u128 { 0xc3727a337a8b704aULL, 0x98165af37b2153deULL }, |
1041 | 0 | u128 { 0x744f18c0592e4c5cULL, 0xbe1bf1b059e9a8d6ULL }, |
1042 | 0 | u128 { 0x1162def06f79df73ULL, 0xeda2ee1c7064130cULL }, |
1043 | 0 | u128 { 0x8addcb5645ac2ba8ULL, 0x9485d4d1c63e8be7ULL }, |
1044 | 0 | u128 { 0x6d953e2bd7173692ULL, 0xb9a74a0637ce2ee1ULL }, |
1045 | 0 | u128 { 0xc8fa8db6ccdd0437ULL, 0xe8111c87c5c1ba99ULL }, |
1046 | 0 | u128 { 0x1d9c9892400a22a2ULL, 0x910ab1d4db9914a0ULL }, |
1047 | 0 | u128 { 0x2503beb6d00cab4bULL, 0xb54d5e4a127f59c8ULL }, |
1048 | 0 | u128 { 0x2e44ae64840fd61dULL, 0xe2a0b5dc971f303aULL }, |
1049 | 0 | u128 { 0x5ceaecfed289e5d2ULL, 0x8da471a9de737e24ULL }, |
1050 | 0 | u128 { 0x7425a83e872c5f47ULL, 0xb10d8e1456105dadULL }, |
1051 | 0 | u128 { 0xd12f124e28f77719ULL, 0xdd50f1996b947518ULL }, |
1052 | 0 | u128 { 0x82bd6b70d99aaa6fULL, 0x8a5296ffe33cc92fULL }, |
1053 | 0 | u128 { 0x636cc64d1001550bULL, 0xace73cbfdc0bfb7bULL }, |
1054 | 0 | u128 { 0x3c47f7e05401aa4eULL, 0xd8210befd30efa5aULL }, |
1055 | 0 | u128 { 0x65acfaec34810a71ULL, 0x8714a775e3e95c78ULL }, |
1056 | 0 | u128 { 0x7f1839a741a14d0dULL, 0xa8d9d1535ce3b396ULL }, |
1057 | 0 | u128 { 0x1ede48111209a050ULL, 0xd31045a8341ca07cULL }, |
1058 | 0 | u128 { 0x934aed0aab460432ULL, 0x83ea2b892091e44dULL }, |
1059 | 0 | u128 { 0xf81da84d5617853fULL, 0xa4e4b66b68b65d60ULL }, |
1060 | 0 | u128 { 0x36251260ab9d668eULL, 0xce1de40642e3f4b9ULL }, |
1061 | 0 | u128 { 0xc1d72b7c6b426019ULL, 0x80d2ae83e9ce78f3ULL }, |
1062 | 0 | u128 { 0xb24cf65b8612f81fULL, 0xa1075a24e4421730ULL }, |
1063 | 0 | u128 { 0xdee033f26797b627ULL, 0xc94930ae1d529cfcULL }, |
1064 | 0 | u128 { 0x169840ef017da3b1ULL, 0xfb9b7cd9a4a7443cULL }, |
1065 | 0 | u128 { 0x8e1f289560ee864eULL, 0x9d412e0806e88aa5ULL }, |
1066 | 0 | u128 { 0xf1a6f2bab92a27e2ULL, 0xc491798a08a2ad4eULL }, |
1067 | 0 | u128 { 0xae10af696774b1dbULL, 0xf5b5d7ec8acb58a2ULL }, |
1068 | 0 | u128 { 0xacca6da1e0a8ef29ULL, 0x9991a6f3d6bf1765ULL }, |
1069 | 0 | u128 { 0x17fd090a58d32af3ULL, 0xbff610b0cc6edd3fULL }, |
1070 | 0 | u128 { 0xddfc4b4cef07f5b0ULL, 0xeff394dcff8a948eULL }, |
1071 | 0 | u128 { 0x4abdaf101564f98eULL, 0x95f83d0a1fb69cd9ULL }, |
1072 | 0 | u128 { 0x9d6d1ad41abe37f1ULL, 0xbb764c4ca7a4440fULL }, |
1073 | 0 | u128 { 0x84c86189216dc5edULL, 0xea53df5fd18d5513ULL }, |
1074 | 0 | u128 { 0x32fd3cf5b4e49bb4ULL, 0x92746b9be2f8552cULL }, |
1075 | 0 | u128 { 0x3fbc8c33221dc2a1ULL, 0xb7118682dbb66a77ULL }, |
1076 | 0 | u128 { 0xfabaf3feaa5334aULL, 0xe4d5e82392a40515ULL }, |
1077 | 0 | u128 { 0x29cb4d87f2a7400eULL, 0x8f05b1163ba6832dULL }, |
1078 | 0 | u128 { 0x743e20e9ef511012ULL, 0xb2c71d5bca9023f8ULL }, |
1079 | 0 | u128 { 0x914da9246b255416ULL, 0xdf78e4b2bd342cf6ULL }, |
1080 | 0 | u128 { 0x1ad089b6c2f7548eULL, 0x8bab8eefb6409c1aULL }, |
1081 | 0 | u128 { 0xa184ac2473b529b1ULL, 0xae9672aba3d0c320ULL }, |
1082 | 0 | u128 { 0xc9e5d72d90a2741eULL, 0xda3c0f568cc4f3e8ULL }, |
1083 | 0 | u128 { 0x7e2fa67c7a658892ULL, 0x8865899617fb1871ULL }, |
1084 | 0 | u128 { 0xddbb901b98feeab7ULL, 0xaa7eebfb9df9de8dULL }, |
1085 | 0 | u128 { 0x552a74227f3ea565ULL, 0xd51ea6fa85785631ULL }, |
1086 | 0 | u128 { 0xd53a88958f87275fULL, 0x8533285c936b35deULL }, |
1087 | 0 | u128 { 0x8a892abaf368f137ULL, 0xa67ff273b8460356ULL }, |
1088 | 0 | u128 { 0x2d2b7569b0432d85ULL, 0xd01fef10a657842cULL }, |
1089 | 0 | u128 { 0x9c3b29620e29fc73ULL, 0x8213f56a67f6b29bULL }, |
1090 | 0 | u128 { 0x8349f3ba91b47b8fULL, 0xa298f2c501f45f42ULL }, |
1091 | 0 | u128 { 0x241c70a936219a73ULL, 0xcb3f2f7642717713ULL }, |
1092 | 0 | u128 { 0xed238cd383aa0110ULL, 0xfe0efb53d30dd4d7ULL }, |
1093 | 0 | u128 { 0xf4363804324a40aaULL, 0x9ec95d1463e8a506ULL }, |
1094 | 0 | u128 { 0xb143c6053edcd0d5ULL, 0xc67bb4597ce2ce48ULL }, |
1095 | 0 | u128 { 0xdd94b7868e94050aULL, 0xf81aa16fdc1b81daULL }, |
1096 | 0 | u128 { 0xca7cf2b4191c8326ULL, 0x9b10a4e5e9913128ULL }, |
1097 | 0 | u128 { 0xfd1c2f611f63a3f0ULL, 0xc1d4ce1f63f57d72ULL }, |
1098 | 0 | u128 { 0xbc633b39673c8cecULL, 0xf24a01a73cf2dccfULL }, |
1099 | 0 | u128 { 0xd5be0503e085d813ULL, 0x976e41088617ca01ULL }, |
1100 | 0 | u128 { 0x4b2d8644d8a74e18ULL, 0xbd49d14aa79dbc82ULL }, |
1101 | 0 | u128 { 0xddf8e7d60ed1219eULL, 0xec9c459d51852ba2ULL }, |
1102 | 0 | u128 { 0xcabb90e5c942b503ULL, 0x93e1ab8252f33b45ULL }, |
1103 | 0 | u128 { 0x3d6a751f3b936243ULL, 0xb8da1662e7b00a17ULL }, |
1104 | 0 | u128 { 0xcc512670a783ad4ULL, 0xe7109bfba19c0c9dULL }, |
1105 | 0 | u128 { 0x27fb2b80668b24c5ULL, 0x906a617d450187e2ULL }, |
1106 | 0 | u128 { 0xb1f9f660802dedf6ULL, 0xb484f9dc9641e9daULL }, |
1107 | 0 | u128 { 0x5e7873f8a0396973ULL, 0xe1a63853bbd26451ULL }, |
1108 | 0 | u128 { 0xdb0b487b6423e1e8ULL, 0x8d07e33455637eb2ULL }, |
1109 | 0 | u128 { 0x91ce1a9a3d2cda62ULL, 0xb049dc016abc5e5fULL }, |
1110 | 0 | u128 { 0x7641a140cc7810fbULL, 0xdc5c5301c56b75f7ULL }, |
1111 | 0 | u128 { 0xa9e904c87fcb0a9dULL, 0x89b9b3e11b6329baULL }, |
1112 | 0 | u128 { 0x546345fa9fbdcd44ULL, 0xac2820d9623bf429ULL }, |
1113 | 0 | u128 { 0xa97c177947ad4095ULL, 0xd732290fbacaf133ULL }, |
1114 | 0 | u128 { 0x49ed8eabcccc485dULL, 0x867f59a9d4bed6c0ULL }, |
1115 | 0 | u128 { 0x5c68f256bfff5a74ULL, 0xa81f301449ee8c70ULL }, |
1116 | 0 | u128 { 0x73832eec6fff3111ULL, 0xd226fc195c6a2f8cULL }, |
1117 | 0 | u128 { 0xc831fd53c5ff7eabULL, 0x83585d8fd9c25db7ULL }, |
1118 | 0 | u128 { 0xba3e7ca8b77f5e55ULL, 0xa42e74f3d032f525ULL }, |
1119 | 0 | u128 { 0x28ce1bd2e55f35ebULL, 0xcd3a1230c43fb26fULL }, |
1120 | 0 | u128 { 0x7980d163cf5b81b3ULL, 0x80444b5e7aa7cf85ULL }, |
1121 | 0 | u128 { 0xd7e105bcc332621fULL, 0xa0555e361951c366ULL }, |
1122 | 0 | u128 { 0x8dd9472bf3fefaa7ULL, 0xc86ab5c39fa63440ULL }, |
1123 | 0 | u128 { 0xb14f98f6f0feb951ULL, 0xfa856334878fc150ULL }, |
1124 | 0 | u128 { 0x6ed1bf9a569f33d3ULL, 0x9c935e00d4b9d8d2ULL }, |
1125 | 0 | u128 { 0xa862f80ec4700c8ULL, 0xc3b8358109e84f07ULL }, |
1126 | 0 | u128 { 0xcd27bb612758c0faULL, 0xf4a642e14c6262c8ULL }, |
1127 | 0 | u128 { 0x8038d51cb897789cULL, 0x98e7e9cccfbd7dbdULL }, |
1128 | 0 | u128 { 0xe0470a63e6bd56c3ULL, 0xbf21e44003acdd2cULL }, |
1129 | 0 | u128 { 0x1858ccfce06cac74ULL, 0xeeea5d5004981478ULL }, |
1130 | 0 | u128 { 0xf37801e0c43ebc8ULL, 0x95527a5202df0ccbULL }, |
1131 | 0 | u128 { 0xd30560258f54e6baULL, 0xbaa718e68396cffdULL }, |
1132 | 0 | u128 { 0x47c6b82ef32a2069ULL, 0xe950df20247c83fdULL }, |
1133 | 0 | u128 { 0x4cdc331d57fa5441ULL, 0x91d28b7416cdd27eULL }, |
1134 | 0 | u128 { 0xe0133fe4adf8e952ULL, 0xb6472e511c81471dULL }, |
1135 | 0 | u128 { 0x58180fddd97723a6ULL, 0xe3d8f9e563a198e5ULL }, |
1136 | 0 | u128 { 0x570f09eaa7ea7648ULL, 0x8e679c2f5e44ff8fULL }, |
1137 | 0 | }; |
1138 | 0 | return values; |
1139 | 0 | } |
1140 | | |
1141 | | static constexpr auto pre_computed_powers_of_five = pre_compute_table(); |
1142 | | |
1143 | | static constexpr u128 power_of_five(i64 exponent) |
1144 | 202k | { |
1145 | 202k | return pre_computed_powers_of_five[exponent - lowest_exponent]; |
1146 | 202k | } |
1147 | | |
1148 | | struct FloatingPointBuilder { |
1149 | | u64 mantissa = 0; |
1150 | | // This exponent is power of 2 and with the bias already added. |
1151 | | i32 exponent = 0; |
1152 | | |
1153 | | static constexpr i32 invalid_exponent_offset = 32768; |
1154 | | |
1155 | | static FloatingPointBuilder zero() |
1156 | 1.65k | { |
1157 | 1.65k | return { 0, 0 }; |
1158 | 1.65k | } |
1159 | | |
1160 | | template<typename T> |
1161 | | static FloatingPointBuilder infinity() |
1162 | 2.37k | { |
1163 | 2.37k | return { 0, FloatingPointInfo<T>::infinity_exponent() }; |
1164 | 2.37k | } AK::FloatingPointBuilder AK::FloatingPointBuilder::infinity<double>() Line | Count | Source | 1162 | 2.37k | { | 1163 | 2.37k | return { 0, FloatingPointInfo<T>::infinity_exponent() }; | 1164 | 2.37k | } |
Unexecuted instantiation: AK::FloatingPointBuilder AK::FloatingPointBuilder::infinity<float>() |
1165 | | |
1166 | | template<typename T> |
1167 | | static FloatingPointBuilder nan() |
1168 | | { |
1169 | | return { 1ull << (FloatingPointInfo<T>::mantissa_bits() - 1), FloatingPointInfo<T>::infinity_exponent() }; |
1170 | | } |
1171 | | |
1172 | | template<typename T> |
1173 | | static FloatingPointBuilder from_value(T value) |
1174 | 7.86k | { |
1175 | 7.86k | using BitDetails = FloatingPointInfo<T>; |
1176 | 7.86k | auto bits = bit_cast<typename BitDetails::SameSizeUnsigned>(value); |
1177 | | // we ignore negative |
1178 | | |
1179 | 7.86k | FloatingPointBuilder result; |
1180 | 7.86k | i32 bias = BitDetails::mantissa_bits() + BitDetails::exponent_bias(); |
1181 | 7.86k | if ((bits & BitDetails::exponent_mask()) == 0) { |
1182 | | // 0 exponent -> denormal (or zero) |
1183 | 737 | result.exponent = 1 - bias; |
1184 | | // Denormal so _DON'T_ add the implicit 1 |
1185 | 737 | result.mantissa = bits & BitDetails::mantissa_mask(); |
1186 | 7.12k | } else { |
1187 | 7.12k | result.exponent = (bits & BitDetails::exponent_mask()) >> BitDetails::mantissa_bits(); |
1188 | 7.12k | result.exponent -= bias; |
1189 | 7.12k | result.mantissa = (bits & BitDetails::mantissa_mask()) | (1ull << BitDetails::mantissa_bits()); |
1190 | 7.12k | } |
1191 | | |
1192 | 7.86k | return result; |
1193 | 7.86k | } AK::FloatingPointBuilder AK::FloatingPointBuilder::from_value<double>(double) Line | Count | Source | 1174 | 7.86k | { | 1175 | 7.86k | using BitDetails = FloatingPointInfo<T>; | 1176 | 7.86k | auto bits = bit_cast<typename BitDetails::SameSizeUnsigned>(value); | 1177 | | // we ignore negative | 1178 | | | 1179 | 7.86k | FloatingPointBuilder result; | 1180 | 7.86k | i32 bias = BitDetails::mantissa_bits() + BitDetails::exponent_bias(); | 1181 | 7.86k | if ((bits & BitDetails::exponent_mask()) == 0) { | 1182 | | // 0 exponent -> denormal (or zero) | 1183 | 737 | result.exponent = 1 - bias; | 1184 | | // Denormal so _DON'T_ add the implicit 1 | 1185 | 737 | result.mantissa = bits & BitDetails::mantissa_mask(); | 1186 | 7.12k | } else { | 1187 | 7.12k | result.exponent = (bits & BitDetails::exponent_mask()) >> BitDetails::mantissa_bits(); | 1188 | 7.12k | result.exponent -= bias; | 1189 | 7.12k | result.mantissa = (bits & BitDetails::mantissa_mask()) | (1ull << BitDetails::mantissa_bits()); | 1190 | 7.12k | } | 1191 | | | 1192 | 7.86k | return result; | 1193 | 7.86k | } |
Unexecuted instantiation: AK::FloatingPointBuilder AK::FloatingPointBuilder::from_value<float>(float) |
1194 | | |
1195 | | template<typename T> |
1196 | | T to_value(bool is_negative) const |
1197 | 186k | { |
1198 | 186k | if constexpr (IsSame<double, T>) { |
1199 | 186k | VERIFY((mantissa & 0xffe0'0000'0000'0000) == 0); |
1200 | 186k | VERIFY((mantissa & 0xfff0'0000'0000'0000) == 0 || exponent == 1); |
1201 | 186k | VERIFY((exponent & ~(0x7ff)) == 0); |
1202 | 186k | } else { |
1203 | 0 | static_assert(IsSame<float, T>); |
1204 | 0 | VERIFY((mantissa & 0xff00'0000) == 0); |
1205 | 0 | VERIFY((mantissa & 0xff80'0000) == 0 || exponent == 1); |
1206 | 0 | VERIFY((exponent & ~(0xff)) == 0); |
1207 | 0 | } |
1208 | | |
1209 | 186k | using BitSizedUnsigened = BitSizedUnsignedForFloatingPoint<T>; |
1210 | | |
1211 | 186k | BitSizedUnsigened raw_bits = mantissa; |
1212 | 186k | raw_bits |= BitSizedUnsigened(exponent) << FloatingPointInfo<T>::mantissa_bits(); |
1213 | 186k | raw_bits |= BitSizedUnsigened(is_negative) << FloatingPointInfo<T>::sign_bit_index(); |
1214 | 186k | return bit_cast<T>(raw_bits); |
1215 | 186k | } double AK::FloatingPointBuilder::to_value<double>(bool) const Line | Count | Source | 1197 | 186k | { | 1198 | 186k | if constexpr (IsSame<double, T>) { | 1199 | 186k | VERIFY((mantissa & 0xffe0'0000'0000'0000) == 0); | 1200 | 186k | VERIFY((mantissa & 0xfff0'0000'0000'0000) == 0 || exponent == 1); | 1201 | 186k | VERIFY((exponent & ~(0x7ff)) == 0); | 1202 | | } else { | 1203 | | static_assert(IsSame<float, T>); | 1204 | | VERIFY((mantissa & 0xff00'0000) == 0); | 1205 | | VERIFY((mantissa & 0xff80'0000) == 0 || exponent == 1); | 1206 | | VERIFY((exponent & ~(0xff)) == 0); | 1207 | | } | 1208 | | | 1209 | 186k | using BitSizedUnsigened = BitSizedUnsignedForFloatingPoint<T>; | 1210 | | | 1211 | 186k | BitSizedUnsigened raw_bits = mantissa; | 1212 | 186k | raw_bits |= BitSizedUnsigened(exponent) << FloatingPointInfo<T>::mantissa_bits(); | 1213 | 186k | raw_bits |= BitSizedUnsigened(is_negative) << FloatingPointInfo<T>::sign_bit_index(); | 1214 | 186k | return bit_cast<T>(raw_bits); | 1215 | 186k | } |
Unexecuted instantiation: float AK::FloatingPointBuilder::to_value<float>(bool) const |
1216 | | }; |
1217 | | |
1218 | | template<typename T> |
1219 | | static FloatingPointBuilder parse_arbitrarily_long_floating_point(BasicParseResult& result, FloatingPointBuilder initial); |
1220 | | |
1221 | | static i32 decimal_exponent_to_binary_exponent(i32 exponent) |
1222 | 202k | { |
1223 | 202k | return ((((152170 + 65536) * exponent) >> 16) + 63); |
1224 | 202k | } |
1225 | | |
1226 | | static u128 multiply(u64 a, u64 b) |
1227 | 213k | { |
1228 | 213k | return UFixedBigInt<64>(a).wide_multiply(b); |
1229 | 213k | } |
1230 | | |
1231 | | template<unsigned Precision> |
1232 | | u128 multiplication_approximation(u64 value, i32 exponent) |
1233 | 202k | { |
1234 | 202k | auto z = power_of_five(exponent); |
1235 | | |
1236 | 202k | static_assert(Precision < 64); |
1237 | 202k | constexpr u64 mask = NumericLimits<u64>::max() >> Precision; |
1238 | | |
1239 | 202k | auto lower_result = multiply(z.high(), value); |
1240 | | |
1241 | 202k | if ((lower_result.high() & mask) == mask) { |
1242 | 11.6k | auto upper_result = multiply(z.low(), value); |
1243 | 11.6k | lower_result += upper_result.high(); |
1244 | 11.6k | } |
1245 | | |
1246 | 202k | return lower_result; |
1247 | 202k | } AK::Detail::UFixedBigInt<128ul, AK::Detail::StaticStorage<false, 128ul> > AK::multiplication_approximation<55u>(unsigned long, int) Line | Count | Source | 1233 | 202k | { | 1234 | 202k | auto z = power_of_five(exponent); | 1235 | | | 1236 | 202k | static_assert(Precision < 64); | 1237 | 202k | constexpr u64 mask = NumericLimits<u64>::max() >> Precision; | 1238 | | | 1239 | 202k | auto lower_result = multiply(z.high(), value); | 1240 | | | 1241 | 202k | if ((lower_result.high() & mask) == mask) { | 1242 | 11.6k | auto upper_result = multiply(z.low(), value); | 1243 | 11.6k | lower_result += upper_result.high(); | 1244 | 11.6k | } | 1245 | | | 1246 | 202k | return lower_result; | 1247 | 202k | } |
Unexecuted instantiation: AK::Detail::UFixedBigInt<128ul, AK::Detail::StaticStorage<false, 128ul> > AK::multiplication_approximation<26u>(unsigned long, int) |
1248 | | |
1249 | | template<typename T> |
1250 | | static FloatingPointBuilder not_enough_precision_binary_to_decimal(i64 exponent, u64 mantissa, int leading_zeros) |
1251 | 11.0k | { |
1252 | 11.0k | using FloatingPointRepr = FloatingPointInfo<T>; |
1253 | 11.0k | i32 did_not_have_upper_bit = static_cast<i32>(mantissa >> 63) ^ 1; |
1254 | 11.0k | FloatingPointBuilder answer; |
1255 | 11.0k | answer.mantissa = mantissa << did_not_have_upper_bit; |
1256 | | |
1257 | 11.0k | i32 bias = FloatingPointRepr::mantissa_bits() + FloatingPointRepr::exponent_bias(); |
1258 | 11.0k | answer.exponent = decimal_exponent_to_binary_exponent(static_cast<i32>(exponent)) - leading_zeros - did_not_have_upper_bit - 62 + bias; |
1259 | | // Make it negative to show we need more precision. |
1260 | 11.0k | answer.exponent -= FloatingPointBuilder::invalid_exponent_offset; |
1261 | 11.0k | VERIFY(answer.exponent < 0); |
1262 | 11.0k | return answer; |
1263 | 11.0k | } FloatingPointStringConversions.cpp:AK::FloatingPointBuilder AK::not_enough_precision_binary_to_decimal<double>(long, unsigned long, int) Line | Count | Source | 1251 | 11.0k | { | 1252 | 11.0k | using FloatingPointRepr = FloatingPointInfo<T>; | 1253 | 11.0k | i32 did_not_have_upper_bit = static_cast<i32>(mantissa >> 63) ^ 1; | 1254 | 11.0k | FloatingPointBuilder answer; | 1255 | 11.0k | answer.mantissa = mantissa << did_not_have_upper_bit; | 1256 | | | 1257 | 11.0k | i32 bias = FloatingPointRepr::mantissa_bits() + FloatingPointRepr::exponent_bias(); | 1258 | 11.0k | answer.exponent = decimal_exponent_to_binary_exponent(static_cast<i32>(exponent)) - leading_zeros - did_not_have_upper_bit - 62 + bias; | 1259 | | // Make it negative to show we need more precision. | 1260 | 11.0k | answer.exponent -= FloatingPointBuilder::invalid_exponent_offset; | 1261 | 11.0k | VERIFY(answer.exponent < 0); | 1262 | 11.0k | return answer; | 1263 | 11.0k | } |
Unexecuted instantiation: FloatingPointStringConversions.cpp:AK::FloatingPointBuilder AK::not_enough_precision_binary_to_decimal<float>(long, unsigned long, int) |
1264 | | |
1265 | | template<typename T> |
1266 | | static FloatingPointBuilder fallback_binary_to_decimal(u64 mantissa, i64 exponent) |
1267 | 11.0k | { |
1268 | | // We should have caught huge exponents already |
1269 | 11.0k | VERIFY(exponent >= -400 && exponent <= 400); |
1270 | | |
1271 | | // Perform the initial steps of binary_to_decimal. |
1272 | 11.0k | auto w = mantissa; |
1273 | 11.0k | auto leading_zeros = count_leading_zeroes(mantissa); |
1274 | 11.0k | w <<= leading_zeros; |
1275 | | |
1276 | 11.0k | auto product = multiplication_approximation<FloatingPointInfo<T>::mantissa_bits() + 3>(w, exponent); |
1277 | | |
1278 | 11.0k | return not_enough_precision_binary_to_decimal<T>(exponent, product.high(), leading_zeros); |
1279 | 11.0k | } FloatingPointStringConversions.cpp:AK::FloatingPointBuilder AK::fallback_binary_to_decimal<double>(unsigned long, long) Line | Count | Source | 1267 | 11.0k | { | 1268 | | // We should have caught huge exponents already | 1269 | 11.0k | VERIFY(exponent >= -400 && exponent <= 400); | 1270 | | | 1271 | | // Perform the initial steps of binary_to_decimal. | 1272 | 11.0k | auto w = mantissa; | 1273 | 11.0k | auto leading_zeros = count_leading_zeroes(mantissa); | 1274 | 11.0k | w <<= leading_zeros; | 1275 | | | 1276 | 11.0k | auto product = multiplication_approximation<FloatingPointInfo<T>::mantissa_bits() + 3>(w, exponent); | 1277 | | | 1278 | 11.0k | return not_enough_precision_binary_to_decimal<T>(exponent, product.high(), leading_zeros); | 1279 | 11.0k | } |
Unexecuted instantiation: FloatingPointStringConversions.cpp:AK::FloatingPointBuilder AK::fallback_binary_to_decimal<float>(unsigned long, long) |
1280 | | |
1281 | | template<typename T> |
1282 | | static FloatingPointBuilder binary_to_decimal(u64 mantissa, i64 exponent) |
1283 | 194k | { |
1284 | 194k | using FloatingPointRepr = FloatingPointInfo<T>; |
1285 | | |
1286 | 194k | if (mantissa == 0 || exponent < FloatingPointRepr::min_power_of_10()) |
1287 | 1.40k | return FloatingPointBuilder::zero(); |
1288 | | |
1289 | | // Max double value which isn't negative is xe308 |
1290 | 193k | if (exponent > FloatingPointRepr::max_power_of_10()) |
1291 | 2.16k | return FloatingPointBuilder::infinity<T>(); |
1292 | | |
1293 | 191k | auto w = mantissa; |
1294 | | // Normalize the decimal significand w by shifting it so that w ∈ [2^63, 2^64) |
1295 | 191k | auto leading_zeros = count_leading_zeroes(mantissa); |
1296 | 191k | w <<= leading_zeros; |
1297 | | |
1298 | | // We need at least mantissa bits + 1 for the implicit bit + 1 for the implicit 0 top bit and one extra for rounding |
1299 | 191k | u128 approximation_of_product_with_power_of_five = multiplication_approximation<FloatingPointRepr::mantissa_bits() + 3>(w, exponent); |
1300 | | |
1301 | | // The paper (and code of fastfloat/fast_float as of writing) mention that the low part |
1302 | | // of approximation_of_product_with_power_of_five can be 2^64 - 1 here in which case we need more |
1303 | | // precision if the exponent lies outside of [-27, 55]. However the authors of the paper have |
1304 | | // shown that this case cannot actually occur. See https://github.com/fastfloat/fast_float/issues/146#issuecomment-1262527329 |
1305 | | |
1306 | 191k | u8 upperbit = approximation_of_product_with_power_of_five.high() >> 63; |
1307 | 191k | auto real_mantissa = approximation_of_product_with_power_of_five.high() >> (upperbit + 64 - FloatingPointRepr::mantissa_bits() - 3); |
1308 | | |
1309 | | // We immediately normalize the exponent to 0 - max else we have to add the bias in most following calculations |
1310 | 191k | i32 power_of_two_with_bias = decimal_exponent_to_binary_exponent(exponent) - leading_zeros + upperbit + FloatingPointRepr::exponent_bias(); |
1311 | | |
1312 | 191k | if (power_of_two_with_bias <= 0) { |
1313 | | // If the exponent is less than the bias we might have a denormal on our hands |
1314 | | // A denormal is a float with exponent zero, which means it doesn't have the implicit |
1315 | | // 1 at the top of the mantissa. |
1316 | | |
1317 | | // If the top bit would be below the bottom of the mantissa we have to round to zero |
1318 | 2.63k | if (power_of_two_with_bias <= -63) |
1319 | 248 | return FloatingPointBuilder::zero(); |
1320 | | |
1321 | | // Otherwise, we have to shift the mantissa to be a denormal |
1322 | 2.38k | auto s = -power_of_two_with_bias + 1; |
1323 | 2.38k | real_mantissa = real_mantissa >> s; |
1324 | | |
1325 | | // And then round ties to even |
1326 | 2.38k | real_mantissa += real_mantissa & 1; |
1327 | 2.38k | real_mantissa >>= 1; |
1328 | | |
1329 | | // Check for subnormal by checking if the 53th bit of the mantissa it set in which case exponent is 1 not 0 |
1330 | | // It is only a real subnormal if the top bit isn't set |
1331 | 2.38k | power_of_two_with_bias = real_mantissa < (1ull << FloatingPointRepr::mantissa_bits()) ? 0 : 1; |
1332 | | |
1333 | 2.38k | return { real_mantissa, power_of_two_with_bias }; |
1334 | 2.63k | } |
1335 | | |
1336 | 188k | if (approximation_of_product_with_power_of_five.low() <= 1 && (real_mantissa & 0b11) == 0b01 |
1337 | 156k | && exponent >= FloatingPointRepr::min_exponent_round_to_even() |
1338 | 155k | && exponent <= FloatingPointRepr::max_exponent_round_to_even()) { |
1339 | | // If the lowest bit is set but the one above it isn't this is a value exactly halfway |
1340 | | // between two floating points |
1341 | | // if (z ÷ 264 )/m is a power of two then m ← m − 1 |
1342 | | |
1343 | | // effectively all discard bits from z.high are 0 |
1344 | 97.6k | if (approximation_of_product_with_power_of_five.high() == (real_mantissa << (upperbit + 64 - FloatingPointRepr::mantissa_bits() - 3))) { |
1345 | 96.8k | real_mantissa &= ~u64(1); |
1346 | 96.8k | } |
1347 | 97.6k | } |
1348 | | |
1349 | 188k | real_mantissa += real_mantissa & 1; |
1350 | 188k | real_mantissa >>= 1; |
1351 | | |
1352 | | // If we overflowed the mantissa round up the exponent |
1353 | 188k | if (real_mantissa >= (2ull << FloatingPointRepr::mantissa_bits())) { |
1354 | 847 | real_mantissa = 1ull << FloatingPointRepr::mantissa_bits(); |
1355 | 847 | ++power_of_two_with_bias; |
1356 | 847 | } |
1357 | | |
1358 | 188k | real_mantissa &= ~(1ull << FloatingPointRepr::mantissa_bits()); |
1359 | | |
1360 | | // We might have rounded exponent up to infinity |
1361 | 188k | if (power_of_two_with_bias >= FloatingPointRepr::infinity_exponent()) |
1362 | 209 | return FloatingPointBuilder::infinity<T>(); |
1363 | | |
1364 | 188k | return { |
1365 | 188k | real_mantissa, power_of_two_with_bias |
1366 | 188k | }; |
1367 | 188k | } FloatingPointStringConversions.cpp:AK::FloatingPointBuilder AK::binary_to_decimal<double>(unsigned long, long) Line | Count | Source | 1283 | 194k | { | 1284 | 194k | using FloatingPointRepr = FloatingPointInfo<T>; | 1285 | | | 1286 | 194k | if (mantissa == 0 || exponent < FloatingPointRepr::min_power_of_10()) | 1287 | 1.40k | return FloatingPointBuilder::zero(); | 1288 | | | 1289 | | // Max double value which isn't negative is xe308 | 1290 | 193k | if (exponent > FloatingPointRepr::max_power_of_10()) | 1291 | 2.16k | return FloatingPointBuilder::infinity<T>(); | 1292 | | | 1293 | 191k | auto w = mantissa; | 1294 | | // Normalize the decimal significand w by shifting it so that w ∈ [2^63, 2^64) | 1295 | 191k | auto leading_zeros = count_leading_zeroes(mantissa); | 1296 | 191k | w <<= leading_zeros; | 1297 | | | 1298 | | // We need at least mantissa bits + 1 for the implicit bit + 1 for the implicit 0 top bit and one extra for rounding | 1299 | 191k | u128 approximation_of_product_with_power_of_five = multiplication_approximation<FloatingPointRepr::mantissa_bits() + 3>(w, exponent); | 1300 | | | 1301 | | // The paper (and code of fastfloat/fast_float as of writing) mention that the low part | 1302 | | // of approximation_of_product_with_power_of_five can be 2^64 - 1 here in which case we need more | 1303 | | // precision if the exponent lies outside of [-27, 55]. However the authors of the paper have | 1304 | | // shown that this case cannot actually occur. See https://github.com/fastfloat/fast_float/issues/146#issuecomment-1262527329 | 1305 | | | 1306 | 191k | u8 upperbit = approximation_of_product_with_power_of_five.high() >> 63; | 1307 | 191k | auto real_mantissa = approximation_of_product_with_power_of_five.high() >> (upperbit + 64 - FloatingPointRepr::mantissa_bits() - 3); | 1308 | | | 1309 | | // We immediately normalize the exponent to 0 - max else we have to add the bias in most following calculations | 1310 | 191k | i32 power_of_two_with_bias = decimal_exponent_to_binary_exponent(exponent) - leading_zeros + upperbit + FloatingPointRepr::exponent_bias(); | 1311 | | | 1312 | 191k | if (power_of_two_with_bias <= 0) { | 1313 | | // If the exponent is less than the bias we might have a denormal on our hands | 1314 | | // A denormal is a float with exponent zero, which means it doesn't have the implicit | 1315 | | // 1 at the top of the mantissa. | 1316 | | | 1317 | | // If the top bit would be below the bottom of the mantissa we have to round to zero | 1318 | 2.63k | if (power_of_two_with_bias <= -63) | 1319 | 248 | return FloatingPointBuilder::zero(); | 1320 | | | 1321 | | // Otherwise, we have to shift the mantissa to be a denormal | 1322 | 2.38k | auto s = -power_of_two_with_bias + 1; | 1323 | 2.38k | real_mantissa = real_mantissa >> s; | 1324 | | | 1325 | | // And then round ties to even | 1326 | 2.38k | real_mantissa += real_mantissa & 1; | 1327 | 2.38k | real_mantissa >>= 1; | 1328 | | | 1329 | | // Check for subnormal by checking if the 53th bit of the mantissa it set in which case exponent is 1 not 0 | 1330 | | // It is only a real subnormal if the top bit isn't set | 1331 | 2.38k | power_of_two_with_bias = real_mantissa < (1ull << FloatingPointRepr::mantissa_bits()) ? 0 : 1; | 1332 | | | 1333 | 2.38k | return { real_mantissa, power_of_two_with_bias }; | 1334 | 2.63k | } | 1335 | | | 1336 | 188k | if (approximation_of_product_with_power_of_five.low() <= 1 && (real_mantissa & 0b11) == 0b01 | 1337 | 156k | && exponent >= FloatingPointRepr::min_exponent_round_to_even() | 1338 | 155k | && exponent <= FloatingPointRepr::max_exponent_round_to_even()) { | 1339 | | // If the lowest bit is set but the one above it isn't this is a value exactly halfway | 1340 | | // between two floating points | 1341 | | // if (z ÷ 264 )/m is a power of two then m ← m − 1 | 1342 | | | 1343 | | // effectively all discard bits from z.high are 0 | 1344 | 97.6k | if (approximation_of_product_with_power_of_five.high() == (real_mantissa << (upperbit + 64 - FloatingPointRepr::mantissa_bits() - 3))) { | 1345 | 96.8k | real_mantissa &= ~u64(1); | 1346 | 96.8k | } | 1347 | 97.6k | } | 1348 | | | 1349 | 188k | real_mantissa += real_mantissa & 1; | 1350 | 188k | real_mantissa >>= 1; | 1351 | | | 1352 | | // If we overflowed the mantissa round up the exponent | 1353 | 188k | if (real_mantissa >= (2ull << FloatingPointRepr::mantissa_bits())) { | 1354 | 847 | real_mantissa = 1ull << FloatingPointRepr::mantissa_bits(); | 1355 | 847 | ++power_of_two_with_bias; | 1356 | 847 | } | 1357 | | | 1358 | 188k | real_mantissa &= ~(1ull << FloatingPointRepr::mantissa_bits()); | 1359 | | | 1360 | | // We might have rounded exponent up to infinity | 1361 | 188k | if (power_of_two_with_bias >= FloatingPointRepr::infinity_exponent()) | 1362 | 209 | return FloatingPointBuilder::infinity<T>(); | 1363 | | | 1364 | 188k | return { | 1365 | 188k | real_mantissa, power_of_two_with_bias | 1366 | 188k | }; | 1367 | 188k | } |
Unexecuted instantiation: FloatingPointStringConversions.cpp:AK::FloatingPointBuilder AK::binary_to_decimal<float>(unsigned long, long) |
1368 | | |
1369 | | class MinimalBigInt { |
1370 | | using Ops = StorageOperations<>; |
1371 | | |
1372 | | public: |
1373 | 11.0k | MinimalBigInt() = default; |
1374 | | MinimalBigInt(u64 value) |
1375 | 7.86k | { |
1376 | 7.86k | Ops::copy(Detail::get_storage_of(value), get_storage(words_in_u64)); |
1377 | 7.86k | } |
1378 | | |
1379 | | static MinimalBigInt from_decimal_floating_point(BasicParseResult const& parse_result, size_t& digits_parsed, size_t max_total_digits) |
1380 | 11.0k | { |
1381 | 11.0k | size_t current_word_counter = 0; |
1382 | | // 10**19 is the biggest power of ten which fits in 64 bit |
1383 | 11.0k | constexpr size_t max_word_counter = max_representable_power_of_ten_in_u64; |
1384 | | |
1385 | 11.0k | u64 current_word = 0; |
1386 | | |
1387 | 11.0k | enum AddDigitResult { |
1388 | 11.0k | DidNotHitMaxDigits, |
1389 | 11.0k | HitMaxDigits, |
1390 | 11.0k | }; |
1391 | | |
1392 | 11.0k | auto does_truncate_non_zero = [](char const* parse_head, char const* parse_end) { |
1393 | 65.2k | while (parse_end - parse_head >= 8) { |
1394 | 61.9k | static_assert('0' == 0x30); |
1395 | | |
1396 | 61.9k | if (read_eight_digits(parse_head) != 0x3030303030303030) |
1397 | 1.00k | return true; |
1398 | | |
1399 | 60.9k | parse_head += 8; |
1400 | 60.9k | } |
1401 | | |
1402 | 11.5k | while (parse_head != parse_end) { |
1403 | 8.98k | if (*parse_head != '0') |
1404 | 721 | return true; |
1405 | | |
1406 | 8.26k | ++parse_head; |
1407 | 8.26k | } |
1408 | | |
1409 | 2.52k | return false; |
1410 | 3.24k | }; |
1411 | | |
1412 | 11.0k | MinimalBigInt value; |
1413 | 20.5k | auto add_digits = [&](StringView digits, bool check_fraction_for_truncation = false) { |
1414 | 20.5k | char const* parse_head = digits.characters_without_null_termination(); |
1415 | 20.5k | char const* parse_end = digits.characters_without_null_termination() + digits.length(); |
1416 | | |
1417 | 20.5k | if (digits_parsed == 0) { |
1418 | | // Skip all leading zeros as long as we haven't hit a non zero |
1419 | 14.5k | while (parse_head != parse_end && *parse_head == '0') |
1420 | 3.23k | ++parse_head; |
1421 | 11.3k | } |
1422 | | |
1423 | 174k | while (parse_head != parse_end) { |
1424 | 448k | while (max_word_counter - current_word_counter >= 8 |
1425 | 305k | && parse_end - parse_head >= 8 |
1426 | 293k | && max_total_digits - digits_parsed >= 8) { |
1427 | | |
1428 | 291k | current_word = current_word * 100'000'000 + eight_digits_to_value(read_eight_digits(parse_head)); |
1429 | | |
1430 | 291k | digits_parsed += 8; |
1431 | 291k | current_word_counter += 8; |
1432 | 291k | parse_head += 8; |
1433 | 291k | } |
1434 | | |
1435 | 607k | while (current_word_counter < max_word_counter |
1436 | 465k | && parse_head != parse_end |
1437 | 452k | && digits_parsed < max_total_digits) { |
1438 | | |
1439 | 450k | current_word = current_word * 10 + (*parse_head - '0'); |
1440 | | |
1441 | 450k | ++digits_parsed; |
1442 | 450k | ++current_word_counter; |
1443 | 450k | ++parse_head; |
1444 | 450k | } |
1445 | | |
1446 | 157k | if (digits_parsed == max_total_digits) { |
1447 | | // Check if we are leaving behind any non zero |
1448 | 3.14k | bool truncated = does_truncate_non_zero(parse_head, parse_end); |
1449 | 3.14k | if (auto fraction = parse_result.fractional_part; check_fraction_for_truncation && !fraction.is_empty()) |
1450 | 1.35k | truncated = truncated || does_truncate_non_zero(fraction.characters_without_null_termination(), fraction.characters_without_null_termination() + fraction.length()); |
1451 | | |
1452 | | // If we truncated we just pretend there is another 1 after the already parsed digits |
1453 | | |
1454 | 3.14k | if (truncated && current_word_counter != max_word_counter) { |
1455 | | // If it still fits in the current add it there, this saves a wide multiply |
1456 | 1.50k | current_word = current_word * 10 + 1; |
1457 | 1.50k | ++current_word_counter; |
1458 | 1.50k | truncated = false; |
1459 | 1.50k | } |
1460 | 3.14k | value.add_digits(current_word, current_word_counter); |
1461 | | |
1462 | | // If it didn't fit just do * 10 + 1 |
1463 | 3.14k | if (truncated) |
1464 | 225 | value.add_digits(1, 1); |
1465 | | |
1466 | 3.14k | return HitMaxDigits; |
1467 | 153k | } else { |
1468 | 153k | value.add_digits(current_word, current_word_counter); |
1469 | 153k | current_word = 0; |
1470 | 153k | current_word_counter = 0; |
1471 | 153k | } |
1472 | 157k | } |
1473 | | |
1474 | 17.3k | return DidNotHitMaxDigits; |
1475 | 20.5k | }; |
1476 | | |
1477 | 11.0k | if (add_digits(parse_result.whole_part, true) == HitMaxDigits) |
1478 | 1.54k | return value; |
1479 | | |
1480 | 9.49k | add_digits(parse_result.fractional_part); |
1481 | | |
1482 | 9.49k | return value; |
1483 | 11.0k | } |
1484 | | |
1485 | | u64 top_64_bits(bool& has_truncated_bits) const |
1486 | 3.17k | { |
1487 | 3.17k | if (m_used_length == 0) |
1488 | 0 | return 0; |
1489 | | |
1490 | | // Top word should be non-zero |
1491 | 3.17k | VERIFY(m_words[m_used_length - 1] != 0); |
1492 | | |
1493 | 3.17k | auto top_u64_start = static_cast<size_t>(size_in_bits()) - 64; |
1494 | 3.17k | u64 top_u64 = 0; |
1495 | | |
1496 | 20.3k | for (size_t i = 0; i < m_used_length; ++i) { |
1497 | 17.1k | size_t word_start = i * native_word_size; |
1498 | 17.1k | size_t word_end = word_start + native_word_size; |
1499 | | |
1500 | 17.1k | if (top_u64_start < word_end) { |
1501 | 6.04k | if (top_u64_start >= word_start) { |
1502 | 3.17k | auto shift = top_u64_start - word_start; |
1503 | 3.17k | top_u64 = m_words[i] >> shift; |
1504 | 3.17k | has_truncated_bits |= m_words[i] ^ (top_u64 << shift); |
1505 | 3.17k | } else { |
1506 | 2.86k | top_u64 |= static_cast<u64>(m_words[i]) << (word_start - top_u64_start); |
1507 | 2.86k | } |
1508 | 11.1k | } else { |
1509 | 11.1k | has_truncated_bits |= m_words[i]; |
1510 | 11.1k | } |
1511 | 17.1k | } |
1512 | | |
1513 | 3.17k | return top_u64; |
1514 | 3.17k | } |
1515 | | |
1516 | | i32 size_in_bits() const |
1517 | 6.35k | { |
1518 | 6.35k | if (m_used_length == 0) |
1519 | 0 | return 0; |
1520 | | // This is guaranteed to be at most max_words_needed * word_size so not above i32 max |
1521 | 6.35k | return static_cast<i32>(native_word_size * m_used_length) - count_leading_zeroes(m_words[m_used_length - 1]); |
1522 | 6.35k | } |
1523 | | |
1524 | | void multiply_with_power_of_10(u32 exponent) |
1525 | 3.17k | { |
1526 | 3.17k | multiply_with_power_of_5(exponent); |
1527 | 3.17k | multiply_with_power_of_2(exponent); |
1528 | 3.17k | } |
1529 | | |
1530 | | void multiply_with_power_of_5(u32 exponent) |
1531 | 11.0k | { |
1532 | | // FIXME: Using UFixedBigInt here does not feel right. We need to nicely (without |
1533 | | // reinterpret_cast and ifs) convert u64 to NativeWord (if NativeWord == u32) |
1534 | | // and one of UFixedBigInt constructors happens to do this exact job. |
1535 | | // |
1536 | | // To calculate this lookup table, we compute 5 ** (2 ** i) for all i \in [0; 10], split |
1537 | | // numbers into 64-bit words and concatenate the results, writing corresponding sizes to |
1538 | | // `sizes` array in `power_of_5` lambda. |
1539 | 11.0k | static constexpr UFixedBigInt<82 * 64> power_of_5_coefficients = { { |
1540 | 11.0k | 5ull, |
1541 | 11.0k | 25ull, |
1542 | 11.0k | 625ull, |
1543 | 11.0k | 390625ull, |
1544 | 11.0k | 152587890625ull, |
1545 | 11.0k | 3273344365508751233ull, |
1546 | 11.0k | 1262ull, |
1547 | 11.0k | 7942358959831785217ull, |
1548 | 11.0k | 16807427164405733357ull, |
1549 | 11.0k | 1593091ull, |
1550 | 11.0k | 279109966635548161ull, |
1551 | 11.0k | 2554917779393558781ull, |
1552 | 11.0k | 14124656261812188652ull, |
1553 | 11.0k | 11976055582626787546ull, |
1554 | 11.0k | 2537941837315ull, |
1555 | 11.0k | 13750482914757213185ull, |
1556 | 11.0k | 1302999927698857842ull, |
1557 | 11.0k | 14936872543252795590ull, |
1558 | 11.0k | 2788415840139466767ull, |
1559 | 11.0k | 2095640732773017264ull, |
1560 | 11.0k | 7205570348933370714ull, |
1561 | 11.0k | 7348167152523113408ull, |
1562 | 11.0k | 9285516396840364274ull, |
1563 | 11.0k | 6907659600622710236ull, |
1564 | 11.0k | 349175ull, |
1565 | 11.0k | 8643096425819600897ull, |
1566 | 11.0k | 6743743997439985372ull, |
1567 | 11.0k | 14059704609098336919ull, |
1568 | 11.0k | 10729359125898331411ull, |
1569 | 11.0k | 4933048501514368705ull, |
1570 | 11.0k | 12258131603170554683ull, |
1571 | 11.0k | 2172371001088594721ull, |
1572 | 11.0k | 13569903330219142946ull, |
1573 | 11.0k | 13809142207969578845ull, |
1574 | 11.0k | 16716360519037769646ull, |
1575 | 11.0k | 9631256923806107285ull, |
1576 | 11.0k | 12866941232305103710ull, |
1577 | 11.0k | 1397931361048440292ull, |
1578 | 11.0k | 7619627737732970332ull, |
1579 | 11.0k | 12725409486282665900ull, |
1580 | 11.0k | 11703051443360963910ull, |
1581 | 11.0k | 9947078370803086083ull, |
1582 | 11.0k | 13966287901448440471ull, |
1583 | 11.0k | 121923442132ull, |
1584 | 11.0k | 17679772531488845825ull, |
1585 | 11.0k | 2216509366347768155ull, |
1586 | 11.0k | 1568689219195129479ull, |
1587 | 11.0k | 5511594616325588277ull, |
1588 | 11.0k | 1067709417009240089ull, |
1589 | 11.0k | 9070650952098657518ull, |
1590 | 11.0k | 11515285870634858015ull, |
1591 | 11.0k | 2539561553659505564ull, |
1592 | 11.0k | 17604889300961091799ull, |
1593 | 11.0k | 14511540856854204724ull, |
1594 | 11.0k | 12099083339557485471ull, |
1595 | 11.0k | 7115240299237943815ull, |
1596 | 11.0k | 313979240050606788ull, |
1597 | 11.0k | 10004784664717172195ull, |
1598 | 11.0k | 15570268847930131473ull, |
1599 | 11.0k | 10359715202835930803ull, |
1600 | 11.0k | 17685054012115162812ull, |
1601 | 11.0k | 13183273382855797757ull, |
1602 | 11.0k | 7743260039872919062ull, |
1603 | 11.0k | 9284593436392572926ull, |
1604 | 11.0k | 11105921222066415013ull, |
1605 | 11.0k | 18198799323400703846ull, |
1606 | 11.0k | 16314988383739458320ull, |
1607 | 11.0k | 4387527177871570570ull, |
1608 | 11.0k | 8476708682254672590ull, |
1609 | 11.0k | 4925096874831034057ull, |
1610 | 11.0k | 14075687868072027455ull, |
1611 | 11.0k | 112866656203221926ull, |
1612 | 11.0k | 9852830467773230418ull, |
1613 | 11.0k | 25755239915196746ull, |
1614 | 11.0k | 2201493076310172510ull, |
1615 | 11.0k | 8342165458688466438ull, |
1616 | 11.0k | 13954006576066379050ull, |
1617 | 11.0k | 15193819059903295636ull, |
1618 | 11.0k | 12565616718911389531ull, |
1619 | 11.0k | 3815854855847885129ull, |
1620 | 11.0k | 15696762163583540628ull, |
1621 | 11.0k | 805ull, |
1622 | 11.0k | } }; |
1623 | | |
1624 | | // power_of_5[i] = 5 ** (2 ** i) |
1625 | 11.0k | static constexpr auto power_of_5 = [&] { |
1626 | 11.0k | constexpr size_t powers_count = 11; |
1627 | | |
1628 | 11.0k | Array<UnsignedStorageReadonlySpan, powers_count> result; |
1629 | 11.0k | Array<size_t, powers_count> sizes = { 1, 1, 1, 1, 1, 2, 3, 5, 10, 19, 38 }; |
1630 | | |
1631 | 11.0k | size_t offset = 0; |
1632 | 11.0k | for (size_t i = 0; i < powers_count; ++i) { |
1633 | 11.0k | if constexpr (SameAs<NativeWord, u32>) |
1634 | 11.0k | sizes[i] *= 2; |
1635 | 11.0k | result[i] = UnsignedStorageReadonlySpan(power_of_5_coefficients.span().slice(offset, sizes[i])); |
1636 | 11.0k | offset += sizes[i]; |
1637 | 11.0k | } |
1638 | | |
1639 | 11.0k | return result; |
1640 | 11.0k | }(); |
1641 | | |
1642 | 11.0k | VERIFY(exponent < (1 << power_of_5.size())); |
1643 | | |
1644 | | // Binary exponentiation |
1645 | 132k | for (size_t i = 0; i < power_of_5.size(); ++i) { |
1646 | 121k | if (exponent >> i & 1) { |
1647 | 34.8k | if (power_of_5[i].size() == 1) { |
1648 | 17.8k | multiply_with_small(power_of_5[i][0]); |
1649 | 17.8k | } else { |
1650 | 16.9k | auto copy = *this; |
1651 | 16.9k | Ops::baseline_mul(copy.get_storage(), power_of_5[i], |
1652 | 16.9k | get_storage(m_used_length + power_of_5[i].size()), g_null_allocator); |
1653 | 16.9k | trim_last_word_if_zero(); |
1654 | 16.9k | } |
1655 | 34.8k | } |
1656 | 121k | } |
1657 | 11.0k | } |
1658 | | |
1659 | | void multiply_with_power_of_2(u32 exponent) |
1660 | 10.7k | { |
1661 | 10.7k | if (exponent) { |
1662 | 8.58k | size_t max_new_length = m_used_length + (exponent + native_word_size - 1) / native_word_size; |
1663 | 8.58k | if (m_used_length != max_words_needed) |
1664 | 8.58k | m_words[m_used_length] = 0; |
1665 | 8.58k | auto storage = get_storage(max_new_length); |
1666 | | |
1667 | 8.58k | Ops::shift_left(storage, exponent, storage); |
1668 | 8.58k | trim_last_word_if_zero(); |
1669 | 8.58k | } |
1670 | 10.7k | } |
1671 | | |
1672 | | enum class CompareResult { |
1673 | | Equal = 0, |
1674 | | GreaterThan = 1, |
1675 | | LessThan = -1 |
1676 | | }; |
1677 | | |
1678 | | CompareResult compare_to(MinimalBigInt const& other) const |
1679 | 7.86k | { |
1680 | 7.86k | return static_cast<CompareResult>(Ops::compare(get_storage(), other.get_storage(), false)); |
1681 | 7.86k | } |
1682 | | |
1683 | | private: |
1684 | | UnsignedStorageSpan get_storage(size_t new_length = 0) |
1685 | 342k | { |
1686 | 342k | if (new_length > m_used_length) |
1687 | 33.4k | m_used_length = min(max_words_needed, new_length); |
1688 | 342k | return { m_words.data(), m_used_length }; |
1689 | 342k | } |
1690 | | |
1691 | | UnsignedStorageReadonlySpan get_storage() const |
1692 | 15.7k | { |
1693 | 15.7k | return { m_words.data(), m_used_length }; |
1694 | 15.7k | } |
1695 | | |
1696 | | void trim_last_word_if_zero() |
1697 | 25.5k | { |
1698 | 25.5k | if (m_used_length > 0 && !m_words[m_used_length - 1]) |
1699 | 15.4k | --m_used_length; |
1700 | 25.5k | } |
1701 | | |
1702 | | static constexpr Array<u64, 20> powers_of_ten_uint64 = { |
1703 | | 1UL, 10UL, 100UL, 1000UL, 10000UL, 100000UL, 1000000UL, 10000000UL, 100000000UL, |
1704 | | 1000000000UL, 10000000000UL, 100000000000UL, 1000000000000UL, 10000000000000UL, |
1705 | | 100000000000000UL, 1000000000000000UL, 10000000000000000UL, 100000000000000000UL, |
1706 | | 1000000000000000000UL, 10000000000000000000UL |
1707 | | }; |
1708 | | |
1709 | | void multiply_with_small(u64 value) |
1710 | 175k | { |
1711 | 175k | if (value <= max_native_word) { |
1712 | 175k | auto native_value = static_cast<NativeWord>(value); |
1713 | 175k | NativeWord carry = 0; |
1714 | 2.91M | for (size_t i = 0; i < m_used_length; ++i) { |
1715 | 2.73M | auto result = UFixedBigInt<native_word_size>(m_words[i]).wide_multiply(native_value) + carry; |
1716 | 2.73M | carry = result.high(); |
1717 | 2.73M | m_words[i] = result.low(); |
1718 | 2.73M | } |
1719 | 175k | if (carry != 0) |
1720 | 143k | m_words[m_used_length++] = carry; |
1721 | 175k | } else { |
1722 | | // word_size == 32 && value > NumericLimits<u32>::max() |
1723 | 0 | auto copy = *this; |
1724 | 0 | Ops::baseline_mul(copy.get_storage(), Detail::get_storage_of(value), get_storage(m_used_length + 2), g_null_allocator); |
1725 | 0 | trim_last_word_if_zero(); |
1726 | 0 | } |
1727 | 175k | } |
1728 | | |
1729 | | void add_small(u64 value) |
1730 | 157k | { |
1731 | 157k | if (m_used_length == 0 && value <= max_native_word) { |
1732 | 11.0k | m_words[m_used_length++] = static_cast<NativeWord>(value); |
1733 | 11.0k | return; |
1734 | 11.0k | } |
1735 | | |
1736 | 146k | auto initial_storage = get_storage(); |
1737 | 146k | auto expanded_storage = get_storage(max(m_used_length, words_in_u64)); |
1738 | 146k | if (Ops::add<false>(initial_storage, Detail::get_storage_of(value), expanded_storage)) |
1739 | 1.02k | m_words[m_used_length++] = 1; |
1740 | 146k | } |
1741 | | |
1742 | | void add_digits(u64 value, size_t digits_for_value) |
1743 | 157k | { |
1744 | 157k | VERIFY(digits_for_value < powers_of_ten_uint64.size()); |
1745 | | |
1746 | 157k | multiply_with_small(powers_of_ten_uint64[digits_for_value]); |
1747 | 157k | add_small(value); |
1748 | 157k | } |
1749 | | |
1750 | | // The max valid words we might need are log2(10^(769 + 342)), max digits + max exponent |
1751 | | static constexpr size_t words_in_u64 = native_word_size == 64 ? 1 : 2; |
1752 | | static constexpr size_t max_words_needed = 58 * words_in_u64; |
1753 | | |
1754 | | size_t m_used_length = 0; |
1755 | | |
1756 | | // FIXME: This is an array just to avoid allocations, but the max size is only needed for |
1757 | | // massive amount of digits, so a smaller vector would work for most cases. |
1758 | | Array<NativeWord, max_words_needed> m_words {}; |
1759 | | }; |
1760 | | |
1761 | | static bool round_nearest_tie_even(FloatingPointBuilder& value, bool did_truncate_bits, i32 shift) |
1762 | 3.17k | { |
1763 | 3.17k | VERIFY(shift == 11 || shift == 40); |
1764 | 3.17k | u64 mask = (1ull << shift) - 1; |
1765 | 3.17k | u64 halfway = 1ull << (shift - 1); |
1766 | | |
1767 | 3.17k | u64 truncated_bits = value.mantissa & mask; |
1768 | 3.17k | bool is_halfway = truncated_bits == halfway; |
1769 | 3.17k | bool is_above = truncated_bits > halfway; |
1770 | | |
1771 | 3.17k | value.mantissa >>= shift; |
1772 | 3.17k | value.exponent += shift; |
1773 | | |
1774 | 3.17k | bool is_odd = (value.mantissa & 1) == 1; |
1775 | 3.17k | return is_above || (is_halfway && did_truncate_bits) || (is_halfway && is_odd); |
1776 | 3.17k | } |
1777 | | |
1778 | | template<typename T, typename Callback> |
1779 | | static void round(FloatingPointBuilder& value, Callback&& should_round_up) |
1780 | 18.8k | { |
1781 | 18.8k | using FloatingRepr = FloatingPointInfo<T>; |
1782 | | |
1783 | 18.8k | i32 mantissa_shift = 64 - FloatingRepr::mantissa_bits() - 1; |
1784 | 18.8k | if (-value.exponent >= mantissa_shift) { |
1785 | | // This is a denormal so we have to shift???? |
1786 | 1.47k | mantissa_shift = min(-value.exponent + 1, 64); |
1787 | 1.47k | if (should_round_up(value, mantissa_shift)) |
1788 | 259 | ++value.mantissa; |
1789 | | |
1790 | 1.47k | value.exponent = (value.mantissa < (1ull << FloatingRepr::mantissa_bits())) ? 0 : 1; |
1791 | 1.47k | return; |
1792 | 1.47k | } |
1793 | | |
1794 | 17.4k | if (should_round_up(value, mantissa_shift)) |
1795 | 5.11k | ++value.mantissa; |
1796 | | |
1797 | | // Mantissa might have been rounded so if it overflowed increase the exponent |
1798 | 17.4k | if (value.mantissa >= (2ull << FloatingRepr::mantissa_bits())) { |
1799 | 403 | value.mantissa = 0; |
1800 | 403 | ++value.exponent; |
1801 | 17.0k | } else { |
1802 | | // Clear the implicit top bit |
1803 | 17.0k | value.mantissa &= ~(1ull << FloatingRepr::mantissa_bits()); |
1804 | 17.0k | } |
1805 | | |
1806 | | // If we also overflowed the exponent make it infinity! |
1807 | 17.4k | if (value.exponent >= FloatingRepr::infinity_exponent()) { |
1808 | 0 | value.exponent = FloatingRepr::infinity_exponent(); |
1809 | 0 | value.mantissa = 0; |
1810 | 0 | } |
1811 | 17.4k | } FloatingPointStringConversions.cpp:void AK::round<double, AK::build_positive_double<double>(AK::MinimalBigInt&, int)::{lambda(AK::FloatingPointBuilder&, int)#1}>(AK::FloatingPointBuilder&, AK::build_positive_double<double>(AK::MinimalBigInt&, int)::{lambda(AK::FloatingPointBuilder&, int)#1}&&)Line | Count | Source | 1780 | 3.17k | { | 1781 | 3.17k | using FloatingRepr = FloatingPointInfo<T>; | 1782 | | | 1783 | 3.17k | i32 mantissa_shift = 64 - FloatingRepr::mantissa_bits() - 1; | 1784 | 3.17k | if (-value.exponent >= mantissa_shift) { | 1785 | | // This is a denormal so we have to shift???? | 1786 | 0 | mantissa_shift = min(-value.exponent + 1, 64); | 1787 | 0 | if (should_round_up(value, mantissa_shift)) | 1788 | 0 | ++value.mantissa; | 1789 | |
| 1790 | 0 | value.exponent = (value.mantissa < (1ull << FloatingRepr::mantissa_bits())) ? 0 : 1; | 1791 | 0 | return; | 1792 | 0 | } | 1793 | | | 1794 | 3.17k | if (should_round_up(value, mantissa_shift)) | 1795 | 1.72k | ++value.mantissa; | 1796 | | | 1797 | | // Mantissa might have been rounded so if it overflowed increase the exponent | 1798 | 3.17k | if (value.mantissa >= (2ull << FloatingRepr::mantissa_bits())) { | 1799 | 196 | value.mantissa = 0; | 1800 | 196 | ++value.exponent; | 1801 | 2.98k | } else { | 1802 | | // Clear the implicit top bit | 1803 | 2.98k | value.mantissa &= ~(1ull << FloatingRepr::mantissa_bits()); | 1804 | 2.98k | } | 1805 | | | 1806 | | // If we also overflowed the exponent make it infinity! | 1807 | 3.17k | if (value.exponent >= FloatingRepr::infinity_exponent()) { | 1808 | 0 | value.exponent = FloatingRepr::infinity_exponent(); | 1809 | 0 | value.mantissa = 0; | 1810 | 0 | } | 1811 | 3.17k | } |
FloatingPointStringConversions.cpp:_ZN2AKL5roundIdZNS_L30build_negative_exponent_doubleITkNS_22ParseableFloatingPointEdEENS_20FloatingPointBuilderERNS_13MinimalBigIntEiS2_EUlRS2_iE_EEvS5_OT0_ Line | Count | Source | 1780 | 7.86k | { | 1781 | 7.86k | using FloatingRepr = FloatingPointInfo<T>; | 1782 | | | 1783 | 7.86k | i32 mantissa_shift = 64 - FloatingRepr::mantissa_bits() - 1; | 1784 | 7.86k | if (-value.exponent >= mantissa_shift) { | 1785 | | // This is a denormal so we have to shift???? | 1786 | 737 | mantissa_shift = min(-value.exponent + 1, 64); | 1787 | 737 | if (should_round_up(value, mantissa_shift)) | 1788 | 0 | ++value.mantissa; | 1789 | | | 1790 | 737 | value.exponent = (value.mantissa < (1ull << FloatingRepr::mantissa_bits())) ? 0 : 1; | 1791 | 737 | return; | 1792 | 737 | } | 1793 | | | 1794 | 7.12k | if (should_round_up(value, mantissa_shift)) | 1795 | 0 | ++value.mantissa; | 1796 | | | 1797 | | // Mantissa might have been rounded so if it overflowed increase the exponent | 1798 | 7.12k | if (value.mantissa >= (2ull << FloatingRepr::mantissa_bits())) { | 1799 | 0 | value.mantissa = 0; | 1800 | 0 | ++value.exponent; | 1801 | 7.12k | } else { | 1802 | | // Clear the implicit top bit | 1803 | 7.12k | value.mantissa &= ~(1ull << FloatingRepr::mantissa_bits()); | 1804 | 7.12k | } | 1805 | | | 1806 | | // If we also overflowed the exponent make it infinity! | 1807 | 7.12k | if (value.exponent >= FloatingRepr::infinity_exponent()) { | 1808 | 0 | value.exponent = FloatingRepr::infinity_exponent(); | 1809 | 0 | value.mantissa = 0; | 1810 | 0 | } | 1811 | 7.12k | } |
FloatingPointStringConversions.cpp:_ZN2AKL5roundIdZNS_L30build_negative_exponent_doubleITkNS_22ParseableFloatingPointEdEENS_20FloatingPointBuilderERNS_13MinimalBigIntEiS2_EUlRS2_iE0_EEvS5_OT0_ Line | Count | Source | 1780 | 7.86k | { | 1781 | 7.86k | using FloatingRepr = FloatingPointInfo<T>; | 1782 | | | 1783 | 7.86k | i32 mantissa_shift = 64 - FloatingRepr::mantissa_bits() - 1; | 1784 | 7.86k | if (-value.exponent >= mantissa_shift) { | 1785 | | // This is a denormal so we have to shift???? | 1786 | 737 | mantissa_shift = min(-value.exponent + 1, 64); | 1787 | 737 | if (should_round_up(value, mantissa_shift)) | 1788 | 259 | ++value.mantissa; | 1789 | | | 1790 | 737 | value.exponent = (value.mantissa < (1ull << FloatingRepr::mantissa_bits())) ? 0 : 1; | 1791 | 737 | return; | 1792 | 737 | } | 1793 | | | 1794 | 7.12k | if (should_round_up(value, mantissa_shift)) | 1795 | 3.39k | ++value.mantissa; | 1796 | | | 1797 | | // Mantissa might have been rounded so if it overflowed increase the exponent | 1798 | 7.12k | if (value.mantissa >= (2ull << FloatingRepr::mantissa_bits())) { | 1799 | 207 | value.mantissa = 0; | 1800 | 207 | ++value.exponent; | 1801 | 6.91k | } else { | 1802 | | // Clear the implicit top bit | 1803 | 6.91k | value.mantissa &= ~(1ull << FloatingRepr::mantissa_bits()); | 1804 | 6.91k | } | 1805 | | | 1806 | | // If we also overflowed the exponent make it infinity! | 1807 | 7.12k | if (value.exponent >= FloatingRepr::infinity_exponent()) { | 1808 | 0 | value.exponent = FloatingRepr::infinity_exponent(); | 1809 | 0 | value.mantissa = 0; | 1810 | 0 | } | 1811 | 7.12k | } |
Unexecuted instantiation: FloatingPointStringConversions.cpp:void AK::round<float, AK::build_positive_double<float>(AK::MinimalBigInt&, int)::{lambda(AK::FloatingPointBuilder&, int)#1}>(AK::FloatingPointBuilder&, AK::build_positive_double<float>(AK::MinimalBigInt&, int)::{lambda(AK::FloatingPointBuilder&, int)#1}&&)Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZN2AKL5roundIfZNS_L30build_negative_exponent_doubleITkNS_22ParseableFloatingPointEfEENS_20FloatingPointBuilderERNS_13MinimalBigIntEiS2_EUlRS2_iE_EEvS5_OT0_ Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZN2AKL5roundIfZNS_L30build_negative_exponent_doubleITkNS_22ParseableFloatingPointEfEENS_20FloatingPointBuilderERNS_13MinimalBigIntEiS2_EUlRS2_iE0_EEvS5_OT0_ |
1812 | | |
1813 | | template<typename T> |
1814 | | static FloatingPointBuilder build_positive_double(MinimalBigInt& mantissa, i32 exponent) |
1815 | 3.17k | { |
1816 | 3.17k | mantissa.multiply_with_power_of_10(exponent); |
1817 | | |
1818 | 3.17k | FloatingPointBuilder result {}; |
1819 | 3.17k | bool should_round_up_ties = false; |
1820 | | // First we get the 64 most significant bits WARNING not masked to real mantissa yet |
1821 | 3.17k | result.mantissa = mantissa.top_64_bits(should_round_up_ties); |
1822 | | |
1823 | 3.17k | i32 bias = FloatingPointInfo<T>::mantissa_bits() + FloatingPointInfo<T>::exponent_bias(); |
1824 | 3.17k | result.exponent = mantissa.size_in_bits() - 64 + bias; |
1825 | | |
1826 | 3.17k | round<T>(result, [should_round_up_ties](FloatingPointBuilder& value, i32 shift) { |
1827 | 3.17k | return round_nearest_tie_even(value, should_round_up_ties, shift); |
1828 | 3.17k | }); FloatingPointStringConversions.cpp:AK::build_positive_double<double>(AK::MinimalBigInt&, int)::{lambda(AK::FloatingPointBuilder&, int)#1}::operator()(AK::FloatingPointBuilder&, int) constLine | Count | Source | 1826 | 3.17k | round<T>(result, [should_round_up_ties](FloatingPointBuilder& value, i32 shift) { | 1827 | 3.17k | return round_nearest_tie_even(value, should_round_up_ties, shift); | 1828 | 3.17k | }); |
Unexecuted instantiation: FloatingPointStringConversions.cpp:AK::build_positive_double<float>(AK::MinimalBigInt&, int)::{lambda(AK::FloatingPointBuilder&, int)#1}::operator()(AK::FloatingPointBuilder&, int) const |
1829 | 3.17k | return result; |
1830 | 3.17k | } FloatingPointStringConversions.cpp:AK::FloatingPointBuilder AK::build_positive_double<double>(AK::MinimalBigInt&, int) Line | Count | Source | 1815 | 3.17k | { | 1816 | 3.17k | mantissa.multiply_with_power_of_10(exponent); | 1817 | | | 1818 | 3.17k | FloatingPointBuilder result {}; | 1819 | 3.17k | bool should_round_up_ties = false; | 1820 | | // First we get the 64 most significant bits WARNING not masked to real mantissa yet | 1821 | 3.17k | result.mantissa = mantissa.top_64_bits(should_round_up_ties); | 1822 | | | 1823 | 3.17k | i32 bias = FloatingPointInfo<T>::mantissa_bits() + FloatingPointInfo<T>::exponent_bias(); | 1824 | 3.17k | result.exponent = mantissa.size_in_bits() - 64 + bias; | 1825 | | | 1826 | 3.17k | round<T>(result, [should_round_up_ties](FloatingPointBuilder& value, i32 shift) { | 1827 | 3.17k | return round_nearest_tie_even(value, should_round_up_ties, shift); | 1828 | 3.17k | }); | 1829 | 3.17k | return result; | 1830 | 3.17k | } |
Unexecuted instantiation: FloatingPointStringConversions.cpp:AK::FloatingPointBuilder AK::build_positive_double<float>(AK::MinimalBigInt&, int) |
1831 | | |
1832 | | template<ParseableFloatingPoint T> |
1833 | | static FloatingPointBuilder build_negative_exponent_double(MinimalBigInt& mantissa, i32 exponent, FloatingPointBuilder initial) |
1834 | 7.86k | { |
1835 | 7.86k | VERIFY(exponent < 0); |
1836 | | |
1837 | | // Building a fraction from a big integer is harder to understand |
1838 | | // But fundamentely we have mantissa * 10^-e and so divide by 5^f |
1839 | | |
1840 | 7.86k | auto parts_copy = initial; |
1841 | 7.86k | round<T>(parts_copy, [](FloatingPointBuilder& value, i32 shift) { |
1842 | 7.86k | if (shift == 64) |
1843 | 0 | value.mantissa = 0; |
1844 | 7.86k | else |
1845 | 7.86k | value.mantissa >>= shift; |
1846 | | |
1847 | 7.86k | value.exponent += shift; |
1848 | | |
1849 | 7.86k | return false; |
1850 | 7.86k | }); FloatingPointStringConversions.cpp:_ZZN2AKL30build_negative_exponent_doubleITkNS_22ParseableFloatingPointEdEENS_20FloatingPointBuilderERNS_13MinimalBigIntEiS1_ENKUlRS1_iE_clES4_i Line | Count | Source | 1841 | 7.86k | round<T>(parts_copy, [](FloatingPointBuilder& value, i32 shift) { | 1842 | 7.86k | if (shift == 64) | 1843 | 0 | value.mantissa = 0; | 1844 | 7.86k | else | 1845 | 7.86k | value.mantissa >>= shift; | 1846 | | | 1847 | 7.86k | value.exponent += shift; | 1848 | | | 1849 | 7.86k | return false; | 1850 | 7.86k | }); |
Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZN2AKL30build_negative_exponent_doubleITkNS_22ParseableFloatingPointEfEENS_20FloatingPointBuilderERNS_13MinimalBigIntEiS1_ENKUlRS1_iE_clES4_i |
1851 | | |
1852 | 7.86k | T rounded_down_double_value = parts_copy.template to_value<T>(false); |
1853 | 7.86k | auto exact_halfway_builder = FloatingPointBuilder::from_value(rounded_down_double_value); |
1854 | | // halfway is exactly just the next bit 1 (rest implicit zeros) |
1855 | 7.86k | exact_halfway_builder.mantissa <<= 1; |
1856 | 7.86k | exact_halfway_builder.mantissa += 1; |
1857 | 7.86k | --exact_halfway_builder.exponent; |
1858 | | |
1859 | 7.86k | MinimalBigInt rounded_down_full_mantissa { exact_halfway_builder.mantissa }; |
1860 | | |
1861 | | // Scale halfway up with 5**(-e) |
1862 | 7.86k | if (u32 power_of_5 = -exponent; power_of_5 != 0) |
1863 | 7.86k | rounded_down_full_mantissa.multiply_with_power_of_5(power_of_5); |
1864 | | |
1865 | 7.86k | i32 power_of_2 = exact_halfway_builder.exponent - exponent; |
1866 | 7.86k | if (power_of_2 > 0) { |
1867 | | // halfway has lower exponent scale up to real exponent |
1868 | 5.38k | rounded_down_full_mantissa.multiply_with_power_of_2(power_of_2); |
1869 | 5.38k | } else if (power_of_2 < 0) { |
1870 | | // halfway has higher exponent scale original mantissa up to real halfway |
1871 | 2.19k | mantissa.multiply_with_power_of_2(-power_of_2); |
1872 | 2.19k | } |
1873 | | |
1874 | 7.86k | auto compared_to_halfway = mantissa.compare_to(rounded_down_full_mantissa); |
1875 | | |
1876 | 7.86k | round<T>(initial, [compared_to_halfway](FloatingPointBuilder& value, i32 shift) { |
1877 | 7.86k | if (shift == 64) { |
1878 | 0 | value.mantissa = 0; |
1879 | 7.86k | } else { |
1880 | 7.86k | value.mantissa >>= shift; |
1881 | 7.86k | } |
1882 | 7.86k | value.exponent += shift; |
1883 | | |
1884 | 7.86k | if (compared_to_halfway == MinimalBigInt::CompareResult::GreaterThan) |
1885 | 2.97k | return true; |
1886 | 4.88k | if (compared_to_halfway == MinimalBigInt::CompareResult::LessThan) |
1887 | 3.68k | return false; |
1888 | | |
1889 | 1.20k | return (value.mantissa & 1) == 1; |
1890 | 4.88k | }); FloatingPointStringConversions.cpp:_ZZN2AKL30build_negative_exponent_doubleITkNS_22ParseableFloatingPointEdEENS_20FloatingPointBuilderERNS_13MinimalBigIntEiS1_ENKUlRS1_iE0_clES4_i Line | Count | Source | 1876 | 7.86k | round<T>(initial, [compared_to_halfway](FloatingPointBuilder& value, i32 shift) { | 1877 | 7.86k | if (shift == 64) { | 1878 | 0 | value.mantissa = 0; | 1879 | 7.86k | } else { | 1880 | 7.86k | value.mantissa >>= shift; | 1881 | 7.86k | } | 1882 | 7.86k | value.exponent += shift; | 1883 | | | 1884 | 7.86k | if (compared_to_halfway == MinimalBigInt::CompareResult::GreaterThan) | 1885 | 2.97k | return true; | 1886 | 4.88k | if (compared_to_halfway == MinimalBigInt::CompareResult::LessThan) | 1887 | 3.68k | return false; | 1888 | | | 1889 | 1.20k | return (value.mantissa & 1) == 1; | 1890 | 4.88k | }); |
Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZZN2AKL30build_negative_exponent_doubleITkNS_22ParseableFloatingPointEfEENS_20FloatingPointBuilderERNS_13MinimalBigIntEiS1_ENKUlRS1_iE0_clES4_i |
1891 | | |
1892 | 7.86k | return initial; |
1893 | 7.86k | } FloatingPointStringConversions.cpp:_ZN2AKL30build_negative_exponent_doubleITkNS_22ParseableFloatingPointEdEENS_20FloatingPointBuilderERNS_13MinimalBigIntEiS1_ Line | Count | Source | 1834 | 7.86k | { | 1835 | 7.86k | VERIFY(exponent < 0); | 1836 | | | 1837 | | // Building a fraction from a big integer is harder to understand | 1838 | | // But fundamentely we have mantissa * 10^-e and so divide by 5^f | 1839 | | | 1840 | 7.86k | auto parts_copy = initial; | 1841 | 7.86k | round<T>(parts_copy, [](FloatingPointBuilder& value, i32 shift) { | 1842 | 7.86k | if (shift == 64) | 1843 | 7.86k | value.mantissa = 0; | 1844 | 7.86k | else | 1845 | 7.86k | value.mantissa >>= shift; | 1846 | | | 1847 | 7.86k | value.exponent += shift; | 1848 | | | 1849 | 7.86k | return false; | 1850 | 7.86k | }); | 1851 | | | 1852 | 7.86k | T rounded_down_double_value = parts_copy.template to_value<T>(false); | 1853 | 7.86k | auto exact_halfway_builder = FloatingPointBuilder::from_value(rounded_down_double_value); | 1854 | | // halfway is exactly just the next bit 1 (rest implicit zeros) | 1855 | 7.86k | exact_halfway_builder.mantissa <<= 1; | 1856 | 7.86k | exact_halfway_builder.mantissa += 1; | 1857 | 7.86k | --exact_halfway_builder.exponent; | 1858 | | | 1859 | 7.86k | MinimalBigInt rounded_down_full_mantissa { exact_halfway_builder.mantissa }; | 1860 | | | 1861 | | // Scale halfway up with 5**(-e) | 1862 | 7.86k | if (u32 power_of_5 = -exponent; power_of_5 != 0) | 1863 | 7.86k | rounded_down_full_mantissa.multiply_with_power_of_5(power_of_5); | 1864 | | | 1865 | 7.86k | i32 power_of_2 = exact_halfway_builder.exponent - exponent; | 1866 | 7.86k | if (power_of_2 > 0) { | 1867 | | // halfway has lower exponent scale up to real exponent | 1868 | 5.38k | rounded_down_full_mantissa.multiply_with_power_of_2(power_of_2); | 1869 | 5.38k | } else if (power_of_2 < 0) { | 1870 | | // halfway has higher exponent scale original mantissa up to real halfway | 1871 | 2.19k | mantissa.multiply_with_power_of_2(-power_of_2); | 1872 | 2.19k | } | 1873 | | | 1874 | 7.86k | auto compared_to_halfway = mantissa.compare_to(rounded_down_full_mantissa); | 1875 | | | 1876 | 7.86k | round<T>(initial, [compared_to_halfway](FloatingPointBuilder& value, i32 shift) { | 1877 | 7.86k | if (shift == 64) { | 1878 | 7.86k | value.mantissa = 0; | 1879 | 7.86k | } else { | 1880 | 7.86k | value.mantissa >>= shift; | 1881 | 7.86k | } | 1882 | 7.86k | value.exponent += shift; | 1883 | | | 1884 | 7.86k | if (compared_to_halfway == MinimalBigInt::CompareResult::GreaterThan) | 1885 | 7.86k | return true; | 1886 | 7.86k | if (compared_to_halfway == MinimalBigInt::CompareResult::LessThan) | 1887 | 7.86k | return false; | 1888 | | | 1889 | 7.86k | return (value.mantissa & 1) == 1; | 1890 | 7.86k | }); | 1891 | | | 1892 | 7.86k | return initial; | 1893 | 7.86k | } |
Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZN2AKL30build_negative_exponent_doubleITkNS_22ParseableFloatingPointEfEENS_20FloatingPointBuilderERNS_13MinimalBigIntEiS1_ |
1894 | | |
1895 | | template<typename T> |
1896 | | static FloatingPointBuilder parse_arbitrarily_long_floating_point(BasicParseResult& result, FloatingPointBuilder initial) |
1897 | 11.0k | { |
1898 | 11.0k | VERIFY(initial.exponent < 0); |
1899 | 11.0k | initial.exponent += FloatingPointBuilder::invalid_exponent_offset; |
1900 | | |
1901 | 11.0k | VERIFY(result.exponent >= NumericLimits<i32>::min() && result.exponent <= NumericLimits<i32>::max()); |
1902 | 11.0k | i32 exponent = static_cast<i32>(result.exponent); |
1903 | 11.0k | { |
1904 | 11.0k | u64 mantissa_copy = result.mantissa; |
1905 | | |
1906 | 55.1k | while (mantissa_copy >= 10000) { |
1907 | 44.1k | mantissa_copy /= 10000; |
1908 | 44.1k | exponent += 4; |
1909 | 44.1k | } |
1910 | | |
1911 | 33.1k | while (mantissa_copy >= 10) { |
1912 | 22.0k | mantissa_copy /= 10; |
1913 | 22.0k | ++exponent; |
1914 | 22.0k | } |
1915 | 11.0k | } |
1916 | | |
1917 | 11.0k | size_t digits = 0; |
1918 | | |
1919 | 11.0k | constexpr auto max_digits_to_parse = FloatingPointInfo<T>::max_possible_digits_needed_for_parsing(); |
1920 | | |
1921 | | // Reparse mantissa into big int |
1922 | 11.0k | auto mantissa = MinimalBigInt::from_decimal_floating_point(result, digits, max_digits_to_parse); |
1923 | | |
1924 | 11.0k | VERIFY(digits <= 1024); |
1925 | | |
1926 | 11.0k | exponent += 1 - static_cast<i32>(digits); |
1927 | | |
1928 | 11.0k | if (exponent >= 0) |
1929 | 3.17k | return build_positive_double<T>(mantissa, exponent); |
1930 | | |
1931 | 7.86k | return build_negative_exponent_double<T>(mantissa, exponent, initial); |
1932 | 11.0k | } FloatingPointStringConversions.cpp:AK::FloatingPointBuilder AK::parse_arbitrarily_long_floating_point<double>(AK::BasicParseResult&, AK::FloatingPointBuilder) Line | Count | Source | 1897 | 11.0k | { | 1898 | 11.0k | VERIFY(initial.exponent < 0); | 1899 | 11.0k | initial.exponent += FloatingPointBuilder::invalid_exponent_offset; | 1900 | | | 1901 | 11.0k | VERIFY(result.exponent >= NumericLimits<i32>::min() && result.exponent <= NumericLimits<i32>::max()); | 1902 | 11.0k | i32 exponent = static_cast<i32>(result.exponent); | 1903 | 11.0k | { | 1904 | 11.0k | u64 mantissa_copy = result.mantissa; | 1905 | | | 1906 | 55.1k | while (mantissa_copy >= 10000) { | 1907 | 44.1k | mantissa_copy /= 10000; | 1908 | 44.1k | exponent += 4; | 1909 | 44.1k | } | 1910 | | | 1911 | 33.1k | while (mantissa_copy >= 10) { | 1912 | 22.0k | mantissa_copy /= 10; | 1913 | 22.0k | ++exponent; | 1914 | 22.0k | } | 1915 | 11.0k | } | 1916 | | | 1917 | 11.0k | size_t digits = 0; | 1918 | | | 1919 | 11.0k | constexpr auto max_digits_to_parse = FloatingPointInfo<T>::max_possible_digits_needed_for_parsing(); | 1920 | | | 1921 | | // Reparse mantissa into big int | 1922 | 11.0k | auto mantissa = MinimalBigInt::from_decimal_floating_point(result, digits, max_digits_to_parse); | 1923 | | | 1924 | 11.0k | VERIFY(digits <= 1024); | 1925 | | | 1926 | 11.0k | exponent += 1 - static_cast<i32>(digits); | 1927 | | | 1928 | 11.0k | if (exponent >= 0) | 1929 | 3.17k | return build_positive_double<T>(mantissa, exponent); | 1930 | | | 1931 | 7.86k | return build_negative_exponent_double<T>(mantissa, exponent, initial); | 1932 | 11.0k | } |
Unexecuted instantiation: FloatingPointStringConversions.cpp:AK::FloatingPointBuilder AK::parse_arbitrarily_long_floating_point<float>(AK::BasicParseResult&, AK::FloatingPointBuilder) |
1933 | | |
1934 | | template<FloatingPoint T> |
1935 | | T parse_result_to_value(BasicParseResult& parse_result) |
1936 | 277k | { |
1937 | 277k | using FloatingPointRepr = FloatingPointInfo<T>; |
1938 | | |
1939 | 277k | if (parse_result.mantissa <= u64(2) << FloatingPointRepr::mantissa_bits() |
1940 | 261k | && parse_result.exponent >= -FloatingPointRepr::max_exact_power_of_10() && parse_result.exponent <= FloatingPointRepr::max_exact_power_of_10() |
1941 | 98.3k | && !parse_result.more_than_19_digits_with_overflow) { |
1942 | | |
1943 | 98.3k | T value = parse_result.mantissa; |
1944 | 98.3k | VERIFY(u64(value) == parse_result.mantissa); |
1945 | | |
1946 | 98.3k | if (parse_result.exponent < 0) |
1947 | 4.11k | value = value / FloatingPointRepr::power_of_ten(-parse_result.exponent); |
1948 | 94.2k | else |
1949 | 94.2k | value = value * FloatingPointRepr::power_of_ten(parse_result.exponent); |
1950 | | |
1951 | 98.3k | if (parse_result.negative) |
1952 | 66.1k | value = -value; |
1953 | | |
1954 | 98.3k | return value; |
1955 | 98.3k | } |
1956 | | |
1957 | 178k | auto floating_point_parts = binary_to_decimal<T>(parse_result.mantissa, parse_result.exponent); |
1958 | 178k | if (parse_result.more_than_19_digits_with_overflow && floating_point_parts.exponent >= 0) { |
1959 | 15.6k | auto rounded_up_double_build = binary_to_decimal<T>(parse_result.mantissa + 1, parse_result.exponent); |
1960 | 15.6k | if (floating_point_parts.mantissa != rounded_up_double_build.mantissa || floating_point_parts.exponent != rounded_up_double_build.exponent) { |
1961 | 11.0k | floating_point_parts = fallback_binary_to_decimal<T>(parse_result.mantissa, parse_result.exponent); |
1962 | 11.0k | VERIFY(floating_point_parts.exponent < 0); |
1963 | 11.0k | } |
1964 | 15.6k | } |
1965 | | |
1966 | 178k | if (floating_point_parts.exponent < 0) { |
1967 | | // Invalid have to parse perfectly |
1968 | 11.0k | floating_point_parts = parse_arbitrarily_long_floating_point<T>(parse_result, floating_point_parts); |
1969 | 11.0k | } |
1970 | | |
1971 | 178k | return floating_point_parts.template to_value<T>(parse_result.negative); |
1972 | 178k | } _ZN2AK21parse_result_to_valueITkNS_8Concepts13FloatingPointEdEET_RNS_16BasicParseResultE Line | Count | Source | 1936 | 277k | { | 1937 | 277k | using FloatingPointRepr = FloatingPointInfo<T>; | 1938 | | | 1939 | 277k | if (parse_result.mantissa <= u64(2) << FloatingPointRepr::mantissa_bits() | 1940 | 261k | && parse_result.exponent >= -FloatingPointRepr::max_exact_power_of_10() && parse_result.exponent <= FloatingPointRepr::max_exact_power_of_10() | 1941 | 98.3k | && !parse_result.more_than_19_digits_with_overflow) { | 1942 | | | 1943 | 98.3k | T value = parse_result.mantissa; | 1944 | 98.3k | VERIFY(u64(value) == parse_result.mantissa); | 1945 | | | 1946 | 98.3k | if (parse_result.exponent < 0) | 1947 | 4.11k | value = value / FloatingPointRepr::power_of_ten(-parse_result.exponent); | 1948 | 94.2k | else | 1949 | 94.2k | value = value * FloatingPointRepr::power_of_ten(parse_result.exponent); | 1950 | | | 1951 | 98.3k | if (parse_result.negative) | 1952 | 66.1k | value = -value; | 1953 | | | 1954 | 98.3k | return value; | 1955 | 98.3k | } | 1956 | | | 1957 | 178k | auto floating_point_parts = binary_to_decimal<T>(parse_result.mantissa, parse_result.exponent); | 1958 | 178k | if (parse_result.more_than_19_digits_with_overflow && floating_point_parts.exponent >= 0) { | 1959 | 15.6k | auto rounded_up_double_build = binary_to_decimal<T>(parse_result.mantissa + 1, parse_result.exponent); | 1960 | 15.6k | if (floating_point_parts.mantissa != rounded_up_double_build.mantissa || floating_point_parts.exponent != rounded_up_double_build.exponent) { | 1961 | 11.0k | floating_point_parts = fallback_binary_to_decimal<T>(parse_result.mantissa, parse_result.exponent); | 1962 | 11.0k | VERIFY(floating_point_parts.exponent < 0); | 1963 | 11.0k | } | 1964 | 15.6k | } | 1965 | | | 1966 | 178k | if (floating_point_parts.exponent < 0) { | 1967 | | // Invalid have to parse perfectly | 1968 | 11.0k | floating_point_parts = parse_arbitrarily_long_floating_point<T>(parse_result, floating_point_parts); | 1969 | 11.0k | } | 1970 | | | 1971 | 178k | return floating_point_parts.template to_value<T>(parse_result.negative); | 1972 | 178k | } |
Unexecuted instantiation: _ZN2AK21parse_result_to_valueITkNS_8Concepts13FloatingPointEfEET_RNS_16BasicParseResultE |
1973 | | |
1974 | | template<FloatingPoint T> |
1975 | | constexpr FloatingPointParseResults<T> parse_result_to_full_result(BasicParseResult parse_result) |
1976 | 278k | { |
1977 | 278k | if (!parse_result.valid) |
1978 | 0 | return { nullptr, FloatingPointError::NoOrInvalidInput, __builtin_nan("") }; |
1979 | | |
1980 | 278k | FloatingPointParseResults<T> full_result {}; |
1981 | 278k | full_result.end_ptr = parse_result.last_parsed; |
1982 | | |
1983 | | // We special case this to be able to differentiate between 0 and values rounded down to 0 |
1984 | 278k | if (parse_result.mantissa == 0) { |
1985 | 793 | full_result.value = parse_result.negative ? -0. : 0.; |
1986 | 793 | return full_result; |
1987 | 793 | } |
1988 | | |
1989 | 277k | full_result.value = parse_result_to_value<T>(parse_result); |
1990 | | |
1991 | | // The only way we can get infinity is from rounding up/down to it. |
1992 | 277k | if (__builtin_isinf(full_result.value)) |
1993 | 1.97k | full_result.error = FloatingPointError::OutOfRange; |
1994 | 275k | else if (full_result.value == T(0.)) |
1995 | 1.34k | full_result.error = FloatingPointError::RoundedDownToZero; |
1996 | | |
1997 | 277k | return full_result; |
1998 | 278k | } _ZN2AK27parse_result_to_full_resultITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EENS_16BasicParseResultE Line | Count | Source | 1976 | 278k | { | 1977 | 278k | if (!parse_result.valid) | 1978 | 0 | return { nullptr, FloatingPointError::NoOrInvalidInput, __builtin_nan("") }; | 1979 | | | 1980 | 278k | FloatingPointParseResults<T> full_result {}; | 1981 | 278k | full_result.end_ptr = parse_result.last_parsed; | 1982 | | | 1983 | | // We special case this to be able to differentiate between 0 and values rounded down to 0 | 1984 | 278k | if (parse_result.mantissa == 0) { | 1985 | 793 | full_result.value = parse_result.negative ? -0. : 0.; | 1986 | 793 | return full_result; | 1987 | 793 | } | 1988 | | | 1989 | 277k | full_result.value = parse_result_to_value<T>(parse_result); | 1990 | | | 1991 | | // The only way we can get infinity is from rounding up/down to it. | 1992 | 277k | if (__builtin_isinf(full_result.value)) | 1993 | 1.97k | full_result.error = FloatingPointError::OutOfRange; | 1994 | 275k | else if (full_result.value == T(0.)) | 1995 | 1.34k | full_result.error = FloatingPointError::RoundedDownToZero; | 1996 | | | 1997 | 277k | return full_result; | 1998 | 278k | } |
Unexecuted instantiation: _ZN2AK27parse_result_to_full_resultITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EENS_16BasicParseResultE |
1999 | | |
2000 | | template<FloatingPoint T> |
2001 | | FloatingPointParseResults<T> parse_first_floating_point(char const* start, char const* end) |
2002 | 278k | { |
2003 | 278k | auto parse_result = parse_numbers( |
2004 | 278k | start, |
2005 | 31.8M | [end](char const* head) { return head == end; },_ZZN2AK26parse_first_floating_pointITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EEPKcS6_ENKUlS6_E_clES6_ Line | Count | Source | 2005 | 31.8M | [end](char const* head) { return head == end; }, |
Unexecuted instantiation: _ZZN2AK26parse_first_floating_pointITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EEPKcS6_ENKUlS6_E_clES6_ |
2006 | 291k | [end](char const* head) { return head - end >= 8; });_ZZN2AK26parse_first_floating_pointITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EEPKcS6_ENKUlS6_E0_clES6_ Line | Count | Source | 2006 | 291k | [end](char const* head) { return head - end >= 8; }); |
Unexecuted instantiation: _ZZN2AK26parse_first_floating_pointITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EEPKcS6_ENKUlS6_E0_clES6_ |
2007 | | |
2008 | 278k | return parse_result_to_full_result<T>(parse_result); |
2009 | 278k | } _ZN2AK26parse_first_floating_pointITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EEPKcS6_ Line | Count | Source | 2002 | 278k | { | 2003 | 278k | auto parse_result = parse_numbers( | 2004 | 278k | start, | 2005 | 278k | [end](char const* head) { return head == end; }, | 2006 | 278k | [end](char const* head) { return head - end >= 8; }); | 2007 | | | 2008 | 278k | return parse_result_to_full_result<T>(parse_result); | 2009 | 278k | } |
Unexecuted instantiation: _ZN2AK26parse_first_floating_pointITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EEPKcS6_ |
2010 | | |
2011 | | template FloatingPointParseResults<double> parse_first_floating_point(char const* start, char const* end); |
2012 | | |
2013 | | template FloatingPointParseResults<float> parse_first_floating_point(char const* start, char const* end); |
2014 | | |
2015 | | template<FloatingPoint T> |
2016 | | FloatingPointParseResults<T> parse_first_floating_point_until_zero_character(char const* start) |
2017 | 0 | { |
2018 | 0 | auto parse_result = parse_numbers( |
2019 | 0 | start, |
2020 | 0 | [](char const* head) { return *head == '\0'; },Unexecuted instantiation: _ZZN2AK47parse_first_floating_point_until_zero_characterITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EEPKcENKUlS6_E_clES6_ Unexecuted instantiation: _ZZN2AK47parse_first_floating_point_until_zero_characterITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EEPKcENKUlS6_E_clES6_ |
2021 | 0 | [](char const*) { return false; });Unexecuted instantiation: _ZZN2AK47parse_first_floating_point_until_zero_characterITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EEPKcENKUlS6_E0_clES6_ Unexecuted instantiation: _ZZN2AK47parse_first_floating_point_until_zero_characterITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EEPKcENKUlS6_E0_clES6_ |
2022 | |
|
2023 | 0 | return parse_result_to_full_result<T>(parse_result); |
2024 | 0 | } Unexecuted instantiation: _ZN2AK47parse_first_floating_point_until_zero_characterITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EEPKc Unexecuted instantiation: _ZN2AK47parse_first_floating_point_until_zero_characterITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EEPKc |
2025 | | |
2026 | | template FloatingPointParseResults<double> parse_first_floating_point_until_zero_character(char const* start); |
2027 | | |
2028 | | template FloatingPointParseResults<float> parse_first_floating_point_until_zero_character(char const* start); |
2029 | | |
2030 | | template<FloatingPoint T> |
2031 | | Optional<T> parse_floating_point_completely(char const* start, char const* end) |
2032 | 0 | { |
2033 | 0 | auto parse_result = parse_numbers( |
2034 | 0 | start, |
2035 | 0 | [end](char const* head) { return head == end; },Unexecuted instantiation: _ZZN2AK31parse_floating_point_completelyITkNS_8Concepts13FloatingPointEdEENS_8OptionalIT_EEPKcS6_ENKUlS6_E_clES6_ Unexecuted instantiation: _ZZN2AK31parse_floating_point_completelyITkNS_8Concepts13FloatingPointEfEENS_8OptionalIT_EEPKcS6_ENKUlS6_E_clES6_ |
2036 | 0 | [end](char const* head) { return head - end >= 8; });Unexecuted instantiation: _ZZN2AK31parse_floating_point_completelyITkNS_8Concepts13FloatingPointEdEENS_8OptionalIT_EEPKcS6_ENKUlS6_E0_clES6_ Unexecuted instantiation: _ZZN2AK31parse_floating_point_completelyITkNS_8Concepts13FloatingPointEfEENS_8OptionalIT_EEPKcS6_ENKUlS6_E0_clES6_ |
2037 | |
|
2038 | 0 | if (!parse_result.valid || parse_result.last_parsed != end) |
2039 | 0 | return {}; |
2040 | | |
2041 | 0 | return parse_result_to_value<T>(parse_result); |
2042 | 0 | } Unexecuted instantiation: _ZN2AK31parse_floating_point_completelyITkNS_8Concepts13FloatingPointEdEENS_8OptionalIT_EEPKcS6_ Unexecuted instantiation: _ZN2AK31parse_floating_point_completelyITkNS_8Concepts13FloatingPointEfEENS_8OptionalIT_EEPKcS6_ |
2043 | | |
2044 | | template Optional<double> parse_floating_point_completely(char const* start, char const* end); |
2045 | | |
2046 | | template Optional<float> parse_floating_point_completely(char const* start, char const* end); |
2047 | | |
2048 | | struct HexFloatParseResult { |
2049 | | bool is_negative = false; |
2050 | | bool valid = false; |
2051 | | char const* last_parsed = nullptr; |
2052 | | u64 mantissa = 0; |
2053 | | i64 exponent = 0; |
2054 | | }; |
2055 | | |
2056 | | static HexFloatParseResult parse_hexfloat(char const* start) |
2057 | 0 | { |
2058 | 0 | HexFloatParseResult result {}; |
2059 | 0 | if (start == nullptr || *start == '\0') |
2060 | 0 | return result; |
2061 | | |
2062 | 0 | char const* parse_head = start; |
2063 | 0 | bool any_digits = false; |
2064 | 0 | bool truncated_non_zero = false; |
2065 | |
|
2066 | 0 | if (*parse_head == '-') { |
2067 | 0 | result.is_negative = true; |
2068 | 0 | ++parse_head; |
2069 | |
|
2070 | 0 | if (*parse_head == '\0' || (!is_ascii_hex_digit(*parse_head) && *parse_head != floating_point_decimal_separator)) |
2071 | 0 | return result; |
2072 | 0 | } else if (*parse_head == '+') { |
2073 | 0 | ++parse_head; |
2074 | |
|
2075 | 0 | if (*parse_head == '\0' || (!is_ascii_hex_digit(*parse_head) && *parse_head != floating_point_decimal_separator)) |
2076 | 0 | return result; |
2077 | 0 | } |
2078 | 0 | if (*parse_head == '0' && (*(parse_head + 1) != '\0') && (*(parse_head + 1) == 'x' || *(parse_head + 1) == 'X')) { |
2079 | | // Skip potential 0[xX], we have to do this here since the sign comes at the front |
2080 | 0 | parse_head += 2; |
2081 | 0 | } |
2082 | |
|
2083 | 0 | auto add_mantissa_digit = [&] { |
2084 | 0 | any_digits = true; |
2085 | | |
2086 | | // We assume you already checked this is actually a digit |
2087 | 0 | auto digit = parse_ascii_hex_digit(*parse_head); |
2088 | | |
2089 | | // Because the power of sixteen is just scaling of power of two we don't |
2090 | | // need to keep all the remaining digits beyond the first 52 bits, just because |
2091 | | // it's easy we store the first 16 digits. However for rounding we do need to parse |
2092 | | // all the digits and keep track if we see any non zero one. |
2093 | 0 | if (result.mantissa < (1ull << 60)) { |
2094 | 0 | result.mantissa = (result.mantissa * 16) + digit; |
2095 | 0 | return true; |
2096 | 0 | } |
2097 | | |
2098 | 0 | if (digit != 0) |
2099 | 0 | truncated_non_zero = true; |
2100 | |
|
2101 | 0 | return false; |
2102 | 0 | }; |
2103 | |
|
2104 | 0 | while (*parse_head != '\0' && is_ascii_hex_digit(*parse_head)) { |
2105 | 0 | add_mantissa_digit(); |
2106 | |
|
2107 | 0 | ++parse_head; |
2108 | 0 | } |
2109 | |
|
2110 | 0 | if (*parse_head != '\0' && *parse_head == floating_point_decimal_separator) { |
2111 | 0 | ++parse_head; |
2112 | 0 | i64 digits_after_separator = 0; |
2113 | 0 | while (*parse_head != '\0' && is_ascii_hex_digit(*parse_head)) { |
2114 | | // Track how many characters we actually read into the mantissa |
2115 | 0 | digits_after_separator += add_mantissa_digit() ? 1 : 0; |
2116 | |
|
2117 | 0 | ++parse_head; |
2118 | 0 | } |
2119 | | |
2120 | | // We parsed x digits after the dot so need to multiply with 2^(-x * 4) |
2121 | | // Since every digit is 4 bits |
2122 | 0 | result.exponent = -digits_after_separator * 4; |
2123 | 0 | } |
2124 | |
|
2125 | 0 | if (!any_digits) |
2126 | 0 | return result; |
2127 | | |
2128 | 0 | if (*parse_head != '\0' && (*parse_head == 'p' || *parse_head == 'P')) { |
2129 | 0 | [&] { |
2130 | 0 | auto const* head_before_p = parse_head; |
2131 | 0 | ArmedScopeGuard reset_ptr { [&] { parse_head = head_before_p; } }; |
2132 | 0 | ++parse_head; |
2133 | |
|
2134 | 0 | if (*parse_head == '\0') |
2135 | 0 | return; |
2136 | | |
2137 | 0 | bool exponent_is_negative = false; |
2138 | 0 | i64 explicit_exponent = 0; |
2139 | |
|
2140 | 0 | if (*parse_head == '-' || *parse_head == '+') { |
2141 | 0 | exponent_is_negative = *parse_head == '-'; |
2142 | 0 | ++parse_head; |
2143 | 0 | if (*parse_head == '\0') |
2144 | 0 | return; |
2145 | 0 | } |
2146 | | |
2147 | 0 | if (!is_ascii_digit(*parse_head)) |
2148 | 0 | return; |
2149 | | |
2150 | | // We have at least one digit (with optional preceding sign) so we will not reset |
2151 | 0 | reset_ptr.disarm(); |
2152 | |
|
2153 | 0 | while (*parse_head != '\0' && is_ascii_digit(*parse_head)) { |
2154 | | // If we hit exponent overflow the number is so huge we are in trouble anyway, see |
2155 | | // a comment in parse_numbers. |
2156 | 0 | if (explicit_exponent < 0x10000000) |
2157 | 0 | explicit_exponent = 10 * explicit_exponent + (*parse_head - '0'); |
2158 | 0 | ++parse_head; |
2159 | 0 | } |
2160 | |
|
2161 | 0 | if (exponent_is_negative) |
2162 | 0 | explicit_exponent = -explicit_exponent; |
2163 | |
|
2164 | 0 | result.exponent += explicit_exponent; |
2165 | 0 | }(); |
2166 | 0 | } |
2167 | |
|
2168 | 0 | result.valid = true; |
2169 | | |
2170 | | // Round up exactly halfway with truncated non zeros, but don't if it would cascade up |
2171 | 0 | if (truncated_non_zero && (result.mantissa & 0xF) != 0xF) { |
2172 | 0 | VERIFY(result.mantissa >= 0x1000'0000'0000'0000); |
2173 | 0 | result.mantissa |= 1; |
2174 | 0 | } |
2175 | | |
2176 | 0 | result.last_parsed = parse_head; |
2177 | |
|
2178 | 0 | return result; |
2179 | 0 | } |
2180 | | |
2181 | | template<FloatingPoint T> |
2182 | | static FloatingPointBuilder build_hex_float(HexFloatParseResult& parse_result) |
2183 | 0 | { |
2184 | 0 | using FloatingPointRepr = FloatingPointInfo<T>; |
2185 | 0 | VERIFY(parse_result.mantissa != 0); |
2186 | | |
2187 | 0 | if (parse_result.exponent >= FloatingPointRepr::infinity_exponent()) |
2188 | 0 | return FloatingPointBuilder::infinity<T>(); |
2189 | | |
2190 | 0 | auto leading_zeros = count_leading_zeroes(parse_result.mantissa); |
2191 | 0 | u64 normalized_mantissa = parse_result.mantissa << leading_zeros; |
2192 | | |
2193 | | // No need to multiply with some power of 5 here the exponent is already a power of 2. |
2194 | |
|
2195 | 0 | u8 upperbit = normalized_mantissa >> 63; |
2196 | 0 | FloatingPointBuilder parts; |
2197 | 0 | parts.mantissa = normalized_mantissa >> (upperbit + 64 - FloatingPointRepr::mantissa_bits() - 3); |
2198 | |
|
2199 | 0 | parts.exponent = parse_result.exponent + upperbit - leading_zeros + FloatingPointRepr::exponent_bias() + 62; |
2200 | |
|
2201 | 0 | if (parts.exponent <= 0) { |
2202 | | // subnormal |
2203 | 0 | if (-parts.exponent + 1 >= 64) { |
2204 | 0 | parts.mantissa = 0; |
2205 | 0 | parts.exponent = 0; |
2206 | 0 | return parts; |
2207 | 0 | } |
2208 | | |
2209 | 0 | parts.mantissa >>= -parts.exponent + 1; |
2210 | 0 | parts.mantissa += parts.mantissa & 1; |
2211 | 0 | parts.mantissa >>= 1; |
2212 | |
|
2213 | 0 | if (parts.mantissa < (1ull << FloatingPointRepr::mantissa_bits())) { |
2214 | 0 | parts.exponent = 0; |
2215 | 0 | } else { |
2216 | 0 | parts.exponent = 1; |
2217 | 0 | } |
2218 | |
|
2219 | 0 | return parts; |
2220 | 0 | } |
2221 | | |
2222 | | // Here we don't have to only do this halfway check for some exponents |
2223 | 0 | if ((parts.mantissa & 0b11) == 0b01) { |
2224 | | // effectively all discard bits from z.high are 0 |
2225 | 0 | if (normalized_mantissa == (parts.mantissa << (upperbit + 64 - FloatingPointRepr::mantissa_bits() - 3))) |
2226 | 0 | parts.mantissa &= ~u64(1); |
2227 | 0 | } |
2228 | |
|
2229 | 0 | parts.mantissa += parts.mantissa & 1; |
2230 | 0 | parts.mantissa >>= 1; |
2231 | |
|
2232 | 0 | if (parts.mantissa >= (2ull << FloatingPointRepr::mantissa_bits())) { |
2233 | 0 | parts.mantissa = 1ull << FloatingPointRepr::mantissa_bits(); |
2234 | 0 | ++parts.exponent; |
2235 | 0 | } |
2236 | |
|
2237 | 0 | parts.mantissa &= ~(1ull << FloatingPointRepr::mantissa_bits()); |
2238 | |
|
2239 | 0 | if (parts.exponent >= FloatingPointRepr::infinity_exponent()) { |
2240 | 0 | parts.mantissa = 0; |
2241 | 0 | parts.exponent = FloatingPointRepr::infinity_exponent(); |
2242 | 0 | } |
2243 | |
|
2244 | 0 | return parts; |
2245 | 0 | } Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZN2AKL15build_hex_floatITkNS_8Concepts13FloatingPointEdEENS_20FloatingPointBuilderERNS_19HexFloatParseResultE Unexecuted instantiation: FloatingPointStringConversions.cpp:_ZN2AKL15build_hex_floatITkNS_8Concepts13FloatingPointEfEENS_20FloatingPointBuilderERNS_19HexFloatParseResultE |
2246 | | |
2247 | | template<FloatingPoint T> |
2248 | | FloatingPointParseResults<T> parse_first_hexfloat_until_zero_character(char const* start) |
2249 | 0 | { |
2250 | 0 | using FloatingPointRepr = FloatingPointInfo<T>; |
2251 | 0 | auto parse_result = parse_hexfloat(start); |
2252 | |
|
2253 | 0 | if (!parse_result.valid) |
2254 | 0 | return { nullptr, FloatingPointError::NoOrInvalidInput, __builtin_nan("") }; |
2255 | | |
2256 | 0 | FloatingPointParseResults<T> full_result {}; |
2257 | 0 | full_result.end_ptr = parse_result.last_parsed; |
2258 | | |
2259 | | // We special case this to be able to differentiate between 0 and values rounded down to 0 |
2260 | |
|
2261 | 0 | if (parse_result.mantissa == 0) { |
2262 | 0 | full_result.value = 0.; |
2263 | 0 | return full_result; |
2264 | 0 | } |
2265 | | |
2266 | 0 | auto result = build_hex_float<T>(parse_result); |
2267 | 0 | full_result.value = result.template to_value<T>(parse_result.is_negative); |
2268 | |
|
2269 | 0 | if (result.exponent == FloatingPointRepr::infinity_exponent()) { |
2270 | 0 | VERIFY(result.mantissa == 0); |
2271 | 0 | full_result.error = FloatingPointError::OutOfRange; |
2272 | 0 | } else if (result.mantissa == 0 && result.exponent == 0) { |
2273 | 0 | full_result.error = FloatingPointError::RoundedDownToZero; |
2274 | 0 | } |
2275 | | |
2276 | 0 | return full_result; |
2277 | 0 | } Unexecuted instantiation: _ZN2AK41parse_first_hexfloat_until_zero_characterITkNS_8Concepts13FloatingPointEdEENS_25FloatingPointParseResultsIT_EEPKc Unexecuted instantiation: _ZN2AK41parse_first_hexfloat_until_zero_characterITkNS_8Concepts13FloatingPointEfEENS_25FloatingPointParseResultsIT_EEPKc |
2278 | | |
2279 | | template FloatingPointParseResults<double> parse_first_hexfloat_until_zero_character(char const* start); |
2280 | | |
2281 | | template FloatingPointParseResults<float> parse_first_hexfloat_until_zero_character(char const* start); |
2282 | | |
2283 | | } |