/src/glaze/include/glaze/util/dragonbox.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2020-2024 Junekey Jeon |
2 | | // |
3 | | // The contents of this file may be used under the terms of |
4 | | // the Apache License v2.0 with LLVM Exceptions. |
5 | | // |
6 | | // (See accompanying file LICENSE-Apache or copy at |
7 | | // https://llvm.org/foundation/relicensing/LICENSE.txt) |
8 | | // |
9 | | // Alternatively, the contents of this file may be used under the terms of |
10 | | // the Boost Software License, Version 1.0. |
11 | | // (See accompanying file LICENSE-Boost or copy at |
12 | | // https://www.boost.org/LICENSE_1_0.txt) |
13 | | // |
14 | | // Unless required by applicable law or agreed to in writing, this software |
15 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
16 | | // KIND, either express or implied. |
17 | | |
18 | | #ifndef GLZ_JKJ_HEADER_DRAGONBOX |
19 | | #define GLZ_JKJ_HEADER_DRAGONBOX |
20 | | |
21 | | // Attribute for storing static data into a dedicated place, e.g. flash memory. Every ODR-used |
22 | | // static data declaration will be decorated with this macro. The users may define this macro, |
23 | | // before including the library headers, into whatever they want. |
24 | | #ifndef GLZ_JKJ_STATIC_DATA_SECTION |
25 | | #define GLZ_JKJ_STATIC_DATA_SECTION |
26 | | #else |
27 | | #define GLZ_JKJ_STATIC_DATA_SECTION_DEFINED 1 |
28 | | #endif |
29 | | |
30 | | // To use the library with toolchains without standard C++ headers, the users may define this macro |
31 | | // into their custom namespace which contains the defintions of all the standard C++ library |
32 | | // features used in this header. (The list can be found below.) |
33 | | #ifndef GLZ_JKJ_STD_REPLACEMENT_NAMESPACE |
34 | | #define GLZ_JKJ_STD_REPLACEMENT_NAMESPACE std |
35 | | #include <cassert> |
36 | | #include <cstdint> |
37 | | #include <cstring> |
38 | | #include <limits> |
39 | | #include <type_traits> |
40 | | |
41 | | #ifdef __has_include |
42 | | #if __has_include(<version>) |
43 | | #include <version> |
44 | | #endif |
45 | | #endif |
46 | | #else |
47 | | #define GLZ_JKJ_STD_REPLACEMENT_NAMESPACE_DEFINED 1 |
48 | | #endif |
49 | | |
50 | | //////////////////////////////////////////////////////////////////////////////////////// |
51 | | // Language feature detections. |
52 | | //////////////////////////////////////////////////////////////////////////////////////// |
53 | | |
54 | | // C++14 constexpr |
55 | | #if defined(__cpp_constexpr) && __cpp_constexpr >= 201304L |
56 | | #define GLZ_JKJ_HAS_CONSTEXPR14 1 |
57 | | #elif __cplusplus >= 201402L |
58 | | #define GLZ_JKJ_HAS_CONSTEXPR14 1 |
59 | | #elif defined(_MSC_VER) && _MSC_VER >= 1910 && _MSVC_LANG >= 201402L |
60 | | #define GLZ_JKJ_HAS_CONSTEXPR14 1 |
61 | | #else |
62 | | #define GLZ_JKJ_HAS_CONSTEXPR14 0 |
63 | | #endif |
64 | | |
65 | | #if GLZ_JKJ_HAS_CONSTEXPR14 |
66 | | #define GLZ_JKJ_CONSTEXPR14 constexpr |
67 | | #else |
68 | | #define GLZ_JKJ_CONSTEXPR14 |
69 | | #endif |
70 | | |
71 | | // C++17 constexpr lambdas |
72 | | #if defined(__cpp_constexpr) && __cpp_constexpr >= 201603L |
73 | | #define GLZ_JKJ_HAS_CONSTEXPR17 1 |
74 | | #elif __cplusplus >= 201703L |
75 | | #define GLZ_JKJ_HAS_CONSTEXPR17 1 |
76 | | #elif defined(_MSC_VER) && _MSC_VER >= 1911 && _MSVC_LANG >= 201703L |
77 | | #define GLZ_JKJ_HAS_CONSTEXPR17 1 |
78 | | #else |
79 | | #define GLZ_JKJ_HAS_CONSTEXPR17 0 |
80 | | #endif |
81 | | |
82 | | // C++17 inline variables |
83 | | #if defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L |
84 | | #define GLZ_JKJ_HAS_INLINE_VARIABLE 1 |
85 | | #elif __cplusplus >= 201703L |
86 | | #define GLZ_JKJ_HAS_INLINE_VARIABLE 1 |
87 | | #elif defined(_MSC_VER) && _MSC_VER >= 1912 && _MSVC_LANG >= 201703L |
88 | | #define GLZ_JKJ_HAS_INLINE_VARIABLE 1 |
89 | | #else |
90 | | #define GLZ_JKJ_HAS_INLINE_VARIABLE 0 |
91 | | #endif |
92 | | |
93 | | #if GLZ_JKJ_HAS_INLINE_VARIABLE |
94 | | #define GLZ_JKJ_INLINE_VARIABLE inline constexpr |
95 | | #else |
96 | | #define GLZ_JKJ_INLINE_VARIABLE static constexpr |
97 | | #endif |
98 | | |
99 | | // C++17 if constexpr |
100 | | #if defined(__cpp_if_constexpr) && __cpp_if_constexpr >= 201606L |
101 | | #define GLZ_JKJ_HAS_IF_CONSTEXPR 1 |
102 | | #elif __cplusplus >= 201703L |
103 | | #define GLZ_JKJ_HAS_IF_CONSTEXPR 1 |
104 | | #elif defined(_MSC_VER) && _MSC_VER >= 1911 && _MSVC_LANG >= 201703L |
105 | | #define GLZ_JKJ_HAS_IF_CONSTEXPR 1 |
106 | | #else |
107 | | #define GLZ_JKJ_HAS_IF_CONSTEXPR 0 |
108 | | #endif |
109 | | |
110 | | #if GLZ_JKJ_HAS_IF_CONSTEXPR |
111 | | #define GLZ_JKJ_IF_CONSTEXPR if constexpr |
112 | | #else |
113 | | #define GLZ_JKJ_IF_CONSTEXPR if |
114 | | #endif |
115 | | |
116 | | // C++20 std::bit_cast |
117 | | #if GLZ_JKJ_STD_REPLACEMENT_NAMESPACE_DEFINED |
118 | | #if GLZ_JKJ_STD_REPLACEMENT_HAS_BIT_CAST |
119 | | #define GLZ_JKJ_HAS_BIT_CAST 1 |
120 | | #else |
121 | | #define GLZ_JKJ_HAS_BIT_CAST 0 |
122 | | #endif |
123 | | #elif defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L |
124 | | #include <bit> |
125 | | #define GLZ_JKJ_HAS_BIT_CAST 1 |
126 | | #else |
127 | | #define GLZ_JKJ_HAS_BIT_CAST 0 |
128 | | #endif |
129 | | |
130 | | // C++23 if consteval or C++20 std::is_constant_evaluated |
131 | | #if defined(__cpp_if_consteval) && __cpp_is_consteval >= 202106L |
132 | | #define GLZ_JKJ_IF_CONSTEVAL if consteval |
133 | | #define GLZ_JKJ_IF_NOT_CONSTEVAL if !consteval |
134 | | #define GLZ_JKJ_CAN_BRANCH_ON_CONSTEVAL 1 |
135 | | #define GLZ_JKJ_USE_IS_CONSTANT_EVALUATED 0 |
136 | | #elif GLZ_JKJ_STD_REPLACEMENT_NAMESPACE_DEFINED |
137 | | #if GLZ_JKJ_STD_REPLACEMENT_HAS_IS_CONSTANT_EVALUATED |
138 | | #define GLZ_JKJ_IF_CONSTEVAL if (stdr::is_constant_evaluated()) |
139 | | #define GLZ_JKJ_IF_NOT_CONSTEVAL if (!stdr::is_constant_evaluated()) |
140 | | #define GLZ_JKJ_CAN_BRANCH_ON_CONSTEVAL 1 |
141 | | #define GLZ_JKJ_USE_IS_CONSTANT_EVALUATED 1 |
142 | | #elif GLZ_JKJ_HAS_IF_CONSTEXPR |
143 | | #define GLZ_JKJ_IF_CONSTEVAL if constexpr (false) |
144 | | #define GLZ_JKJ_IF_NOT_CONSTEVAL if constexpr (true) |
145 | | #define GLZ_JKJ_CAN_BRANCH_ON_CONSTEVAL 0 |
146 | | #define GLZ_JKJ_USE_IS_CONSTANT_EVALUATED 0 |
147 | | #else |
148 | | #define GLZ_JKJ_IF_CONSTEVAL if (false) |
149 | | #define GLZ_JKJ_IF_NOT_CONSTEVAL if (true) |
150 | | #define GLZ_JKJ_CAN_BRANCH_ON_CONSTEVAL 0 |
151 | | #define GLZ_JKJ_USE_IS_CONSTANT_EVALUATED 0 |
152 | | #endif |
153 | | #else |
154 | | #if defined(__cpp_lib_is_constant_evaluated) && __cpp_lib_is_constant_evaluated >= 201811L |
155 | | #define GLZ_JKJ_IF_CONSTEVAL if (stdr::is_constant_evaluated()) |
156 | | #define GLZ_JKJ_IF_NOT_CONSTEVAL if (!stdr::is_constant_evaluated()) |
157 | | #define GLZ_JKJ_CAN_BRANCH_ON_CONSTEVAL 1 |
158 | | #define GLZ_JKJ_USE_IS_CONSTANT_EVALUATED 1 |
159 | | #elif GLZ_JKJ_HAS_IF_CONSTEXPR |
160 | | #define GLZ_JKJ_IF_CONSTEVAL if constexpr (false) |
161 | | #define GLZ_JKJ_IF_NOT_CONSTEVAL if constexpr (true) |
162 | | #define GLZ_JKJ_CAN_BRANCH_ON_CONSTEVAL 0 |
163 | | #define GLZ_JKJ_USE_IS_CONSTANT_EVALUATED 0 |
164 | | #else |
165 | | #define GLZ_JKJ_IF_CONSTEVAL if (false) |
166 | | #define GLZ_JKJ_IF_NOT_CONSTEVAL if (true) |
167 | | #define GLZ_JKJ_CAN_BRANCH_ON_CONSTEVAL 0 |
168 | | #define GLZ_JKJ_USE_IS_CONSTANT_EVALUATED 0 |
169 | | #endif |
170 | | #endif |
171 | | |
172 | | #if GLZ_JKJ_CAN_BRANCH_ON_CONSTEVAL && GLZ_JKJ_HAS_BIT_CAST |
173 | | #define GLZ_JKJ_CONSTEXPR20 constexpr |
174 | | #else |
175 | | #define GLZ_JKJ_CONSTEXPR20 |
176 | | #endif |
177 | | |
178 | | // Suppress additional buffer overrun check. |
179 | | // I have no idea why MSVC thinks some functions here are vulnerable to the buffer overrun |
180 | | // attacks. No, they aren't. |
181 | | #if defined(__GNUC__) || defined(__clang__) |
182 | | #define GLZ_JKJ_SAFEBUFFERS |
183 | | #define GLZ_JKJ_FORCEINLINE inline __attribute__((always_inline)) |
184 | | #elif defined(_MSC_VER) |
185 | | #define GLZ_JKJ_SAFEBUFFERS __declspec(safebuffers) |
186 | | #define GLZ_JKJ_FORCEINLINE __forceinline |
187 | | #else |
188 | | #define GLZ_JKJ_SAFEBUFFERS |
189 | | #define GLZ_JKJ_FORCEINLINE inline |
190 | | #endif |
191 | | |
192 | | #if defined(__has_builtin) |
193 | | #define GLZ_JKJ_HAS_BUILTIN(x) __has_builtin(x) |
194 | | #else |
195 | | #define GLZ_JKJ_HAS_BUILTIN(x) false |
196 | | #endif |
197 | | |
198 | | #if defined(_MSC_VER) |
199 | | #include <intrin.h> |
200 | | #elif defined(__INTEL_COMPILER) |
201 | | #include <immintrin.h> |
202 | | #endif |
203 | | |
204 | | namespace glz::jkj |
205 | | { |
206 | | namespace dragonbox |
207 | | { |
208 | | //////////////////////////////////////////////////////////////////////////////////////// |
209 | | // The Compatibility layer for toolchains without standard C++ headers. |
210 | | //////////////////////////////////////////////////////////////////////////////////////// |
211 | | namespace detail |
212 | | { |
213 | | namespace stdr |
214 | | { |
215 | | // <bit> |
216 | | #if GLZ_JKJ_HAS_BIT_CAST |
217 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::bit_cast; |
218 | | #endif |
219 | | |
220 | | // <cassert> |
221 | | // We need assert() macro, but it is not namespaced anyway, so nothing to do here. |
222 | | |
223 | | // <cstdint> |
224 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::int_fast16_t; |
225 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::int_fast32_t; |
226 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::int_fast8_t; |
227 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::int_least16_t; |
228 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::int_least32_t; |
229 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::int_least8_t; |
230 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::uint_fast16_t; |
231 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::uint_fast32_t; |
232 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::uint_fast8_t; |
233 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::uint_least16_t; |
234 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::uint_least32_t; |
235 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::uint_least64_t; |
236 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::uint_least8_t; |
237 | | // We need INT32_C, UINT32_C and UINT64_C macros too, but again there is nothing to do |
238 | | // here. |
239 | | |
240 | | // <cstring> |
241 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::memcpy; |
242 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::size_t; |
243 | | |
244 | | // <limits> |
245 | | template <class T> |
246 | | using numeric_limits = GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::numeric_limits<T>; |
247 | | |
248 | | // <type_traits> |
249 | | template <bool cond, class T = void> |
250 | | using enable_if = GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::enable_if<cond, T>; |
251 | | template <class T> |
252 | | using add_rvalue_reference = GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::add_rvalue_reference<T>; |
253 | | template <bool cond, class T_true, class T_false> |
254 | | using conditional = GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::conditional<cond, T_true, T_false>; |
255 | | #if GLZ_JKJ_USE_IS_CONSTANT_EVALUATED |
256 | | using GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::is_constant_evaluated; |
257 | | #endif |
258 | | template <class T1, class T2> |
259 | | using is_same = GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::is_same<T1, T2>; |
260 | | #if !GLZ_JKJ_HAS_BIT_CAST |
261 | | template <class T> |
262 | | using is_trivially_copyable = GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::is_trivially_copyable<T>; |
263 | | #endif |
264 | | template <class T> |
265 | | using is_integral = GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::is_integral<T>; |
266 | | template <class T> |
267 | | using is_signed = GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::is_signed<T>; |
268 | | template <class T> |
269 | | using is_unsigned = GLZ_JKJ_STD_REPLACEMENT_NAMESPACE::is_unsigned<T>; |
270 | | } |
271 | | } |
272 | | |
273 | | //////////////////////////////////////////////////////////////////////////////////////// |
274 | | // Some general utilities for C++11-compatibility. |
275 | | //////////////////////////////////////////////////////////////////////////////////////// |
276 | | namespace detail |
277 | | { |
278 | | #if !GLZ_JKJ_HAS_CONSTEXPR17 |
279 | | template <stdr::size_t... indices> |
280 | | struct index_sequence |
281 | | {}; |
282 | | |
283 | | template <stdr::size_t current, stdr::size_t total, class Dummy, stdr::size_t... indices> |
284 | | struct make_index_sequence_impl |
285 | | { |
286 | | using type = typename make_index_sequence_impl<current + 1, total, Dummy, indices..., current>::type; |
287 | | }; |
288 | | |
289 | | template <stdr::size_t total, class Dummy, stdr::size_t... indices> |
290 | | struct make_index_sequence_impl<total, total, Dummy, indices...> |
291 | | { |
292 | | using type = index_sequence<indices...>; |
293 | | }; |
294 | | |
295 | | template <stdr::size_t N> |
296 | | using make_index_sequence = typename make_index_sequence_impl<0, N, void>::type; |
297 | | #endif |
298 | | |
299 | | // Available since C++11, but including <utility> just for this is an overkill. |
300 | | template <class T> |
301 | | typename stdr::add_rvalue_reference<T>::type declval() noexcept; |
302 | | |
303 | | // Similarly, including <array> is an overkill. |
304 | | template <class T, stdr::size_t N> |
305 | | struct array |
306 | | { |
307 | | T data_[N]; |
308 | 0 | constexpr T operator[](stdr::size_t idx) const noexcept { return data_[idx]; } Unexecuted instantiation: glz::jkj::dragonbox::detail::array<unsigned long, 78ul>::operator[](unsigned long) const Unexecuted instantiation: glz::jkj::dragonbox::detail::array<unsigned short, 7ul>::operator[](unsigned long) const Unexecuted instantiation: glz::jkj::dragonbox::detail::array<glz::jkj::dragonbox::detail::wuint::uint128, 619ul>::operator[](unsigned long) const |
309 | 0 | GLZ_JKJ_CONSTEXPR14 T& operator[](stdr::size_t idx) noexcept { return data_[idx]; } Unexecuted instantiation: glz::jkj::dragonbox::detail::array<unsigned long, 6ul>::operator[](unsigned long) Unexecuted instantiation: glz::jkj::dragonbox::detail::array<unsigned short, 7ul>::operator[](unsigned long) Unexecuted instantiation: glz::jkj::dragonbox::detail::array<glz::jkj::dragonbox::detail::wuint::uint128, 23ul>::operator[](unsigned long) Unexecuted instantiation: glz::jkj::dragonbox::detail::array<unsigned long, 27ul>::operator[](unsigned long) |
310 | | }; |
311 | | } |
312 | | |
313 | | //////////////////////////////////////////////////////////////////////////////////////// |
314 | | // Some basic features for encoding/decoding IEEE-754 formats. |
315 | | //////////////////////////////////////////////////////////////////////////////////////// |
316 | | namespace detail |
317 | | { |
318 | | template <class T> |
319 | | struct physical_bits |
320 | | { |
321 | | static constexpr stdr::size_t value = sizeof(T) * stdr::numeric_limits<unsigned char>::digits; |
322 | | }; |
323 | | template <class T> |
324 | | struct value_bits |
325 | | { |
326 | | static constexpr stdr::size_t value = |
327 | | stdr::numeric_limits<typename stdr::enable_if<stdr::is_integral<T>::value, T>::type>::digits; |
328 | | }; |
329 | | |
330 | | template <typename To, typename From> |
331 | | GLZ_JKJ_CONSTEXPR20 To bit_cast(const From& from) |
332 | 0 | { |
333 | 0 | #if GLZ_JKJ_HAS_BIT_CAST |
334 | 0 | return stdr::bit_cast<To>(from); |
335 | 0 | #else |
336 | 0 | static_assert(sizeof(From) == sizeof(To), ""); |
337 | 0 | static_assert(stdr::is_trivially_copyable<To>::value, ""); |
338 | 0 | static_assert(stdr::is_trivially_copyable<From>::value, ""); |
339 | 0 | To to; |
340 | 0 | stdr::memcpy(&to, &from, sizeof(To)); |
341 | 0 | return to; |
342 | 0 | #endif |
343 | 0 | } Unexecuted instantiation: unsigned long glz::jkj::dragonbox::detail::bit_cast<unsigned long, double>(double const&) Unexecuted instantiation: unsigned int glz::jkj::dragonbox::detail::bit_cast<unsigned int, float>(float const&) |
344 | | } |
345 | | |
346 | | // These classes expose encoding specs of IEEE-754-like floating-point formats. |
347 | | // Currently available formats are IEEE-754 binary32 & IEEE-754 binary64. |
348 | | |
349 | | struct ieee754_binary32 |
350 | | { |
351 | | static constexpr int total_bits = 32; |
352 | | static constexpr int significand_bits = 23; |
353 | | static constexpr int exponent_bits = 8; |
354 | | static constexpr int min_exponent = -126; |
355 | | static constexpr int max_exponent = 127; |
356 | | static constexpr int exponent_bias = -127; |
357 | | static constexpr int decimal_significand_digits = 9; |
358 | | static constexpr int decimal_exponent_digits = 2; |
359 | | }; |
360 | | struct ieee754_binary64 |
361 | | { |
362 | | static constexpr int total_bits = 64; |
363 | | static constexpr int significand_bits = 52; |
364 | | static constexpr int exponent_bits = 11; |
365 | | static constexpr int min_exponent = -1022; |
366 | | static constexpr int max_exponent = 1023; |
367 | | static constexpr int exponent_bias = -1023; |
368 | | static constexpr int decimal_significand_digits = 17; |
369 | | static constexpr int decimal_exponent_digits = 3; |
370 | | }; |
371 | | |
372 | | // A floating-point format traits class defines ways to interpret a bit pattern of given size as |
373 | | // an encoding of floating-point number. This is an implementation of such a traits class, |
374 | | // supporting ways to interpret IEEE-754 binary floating-point numbers. |
375 | | template <class Format, class CarrierUInt, class ExponentInt = int> |
376 | | struct ieee754_binary_traits |
377 | | { |
378 | | // CarrierUInt needs to have enough size to hold the entire contents of floating-point |
379 | | // numbers. The actual bits are assumed to be aligned to the LSB, and every other bits are |
380 | | // assumed to be zeroed. |
381 | | static_assert(detail::value_bits<CarrierUInt>::value >= Format::total_bits, |
382 | | "jkj::dragonbox: insufficient number of bits"); |
383 | | static_assert(detail::stdr::is_unsigned<CarrierUInt>::value, ""); |
384 | | |
385 | | // ExponentUInt needs to be large enough to hold (unsigned) exponent bits as well as the |
386 | | // (signed) actual exponent. |
387 | | // TODO: static overflow guard against intermediate computations. |
388 | | static_assert(detail::value_bits<ExponentInt>::value >= Format::exponent_bits + 1, |
389 | | "jkj::dragonbox: insufficient number of bits"); |
390 | | static_assert(detail::stdr::is_signed<ExponentInt>::value, ""); |
391 | | |
392 | | using format = Format; |
393 | | using carrier_uint = CarrierUInt; |
394 | | static constexpr int carrier_bits = int(detail::value_bits<carrier_uint>::value); |
395 | | using exponent_int = ExponentInt; |
396 | | |
397 | | // Extract exponent bits from a bit pattern. |
398 | | // The result must be aligned to the LSB so that there is no additional zero paddings |
399 | | // on the right. This function does not do bias adjustment. |
400 | | static constexpr exponent_int extract_exponent_bits(carrier_uint u) noexcept |
401 | 0 | { |
402 | 0 | return exponent_int((u >> format::significand_bits) & ((exponent_int(1) << format::exponent_bits) - 1)); |
403 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int>::extract_exponent_bits(unsigned long) Unexecuted instantiation: glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int>::extract_exponent_bits(unsigned int) |
404 | | |
405 | | // Extract significand bits from a bit pattern. |
406 | | // The result must be aligned to the LSB so that there is no additional zero paddings |
407 | | // on the right. The result does not contain the implicit bit. |
408 | | static constexpr carrier_uint extract_significand_bits(carrier_uint u) noexcept |
409 | | { |
410 | | return carrier_uint(u & ((carrier_uint(1) << format::significand_bits) - 1u)); |
411 | | } |
412 | | |
413 | | // Remove the exponent bits and extract significand bits together with the sign bit. |
414 | | static constexpr carrier_uint remove_exponent_bits(carrier_uint u) noexcept |
415 | 0 | { |
416 | 0 | return carrier_uint(u & ~(((carrier_uint(1) << format::exponent_bits) - 1u) << format::significand_bits)); |
417 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int>::remove_exponent_bits(unsigned long) Unexecuted instantiation: glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int>::remove_exponent_bits(unsigned int) |
418 | | |
419 | | // Shift the obtained signed significand bits to the left by 1 to remove the sign bit. |
420 | | static constexpr carrier_uint remove_sign_bit_and_shift(carrier_uint u) noexcept |
421 | 0 | { |
422 | 0 | return carrier_uint((carrier_uint(u) << 1) & |
423 | 0 | ((((carrier_uint(1) << (Format::total_bits - 1)) - 1u) << 1) | 1u)); |
424 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int>::remove_sign_bit_and_shift(unsigned long) Unexecuted instantiation: glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int>::remove_sign_bit_and_shift(unsigned int) |
425 | | |
426 | | // Obtain the actual value of the binary exponent from the extracted exponent bits. |
427 | | static constexpr exponent_int binary_exponent(exponent_int exponent_bits) noexcept |
428 | | { |
429 | | return exponent_int(exponent_bits == 0 ? format::min_exponent : exponent_bits + format::exponent_bias); |
430 | | } |
431 | | |
432 | | // Obtain the actual value of the binary significand from the extracted significand bits |
433 | | // and exponent bits. |
434 | | static constexpr carrier_uint binary_significand(carrier_uint significand_bits, |
435 | | exponent_int exponent_bits) noexcept |
436 | | { |
437 | | return carrier_uint(exponent_bits == 0 |
438 | | ? significand_bits |
439 | | : (significand_bits | (carrier_uint(1) << format::significand_bits))); |
440 | | } |
441 | | |
442 | | /* Various boolean observer functions */ |
443 | | |
444 | | static constexpr bool is_nonzero(carrier_uint u) noexcept |
445 | | { |
446 | | return (u & ((carrier_uint(1) << (format::significand_bits + format::exponent_bits)) - 1u)) != 0; |
447 | | } |
448 | | static constexpr bool is_positive(carrier_uint u) noexcept |
449 | | { |
450 | | return u < (carrier_uint(1) << (format::significand_bits + format::exponent_bits)); |
451 | | } |
452 | | static constexpr bool is_negative(carrier_uint u) noexcept { return !is_positive(u); } |
453 | | static constexpr bool is_finite(exponent_int exponent_bits) noexcept |
454 | | { |
455 | | return exponent_bits != ((exponent_int(1) << format::exponent_bits) - 1); |
456 | | } |
457 | | static constexpr bool has_all_zero_significand_bits(carrier_uint u) noexcept |
458 | | { |
459 | | return ((u << 1) & ((((carrier_uint(1) << (Format::total_bits - 1)) - 1u) << 1) | 1u)) == 0; |
460 | | } |
461 | 0 | static constexpr bool has_even_significand_bits(carrier_uint u) noexcept { return u % 2 == 0; } Unexecuted instantiation: glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int>::has_even_significand_bits(unsigned long) Unexecuted instantiation: glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int>::has_even_significand_bits(unsigned int) |
462 | | }; |
463 | | |
464 | | // Convert between bit patterns stored in carrier_uint and instances of an actual |
465 | | // floating-point type. Depending on format and carrier_uint, this operation might not |
466 | | // be possible for some specific bit patterns. However, the contract is that u always |
467 | | // denotes a valid bit pattern, so the functions here are assumed to be noexcept. |
468 | | // Users might specialize this class to change the behavior for certain types. |
469 | | // The default provided by the library is to treat the given floating-point type Float as either |
470 | | // IEEE-754 binary32 or IEEE-754 binary64, depending on the bitwise size of Float. |
471 | | template <class Float> |
472 | | struct default_float_bit_carrier_conversion_traits |
473 | | { |
474 | | // Guards against types that have different internal representations than IEEE-754 |
475 | | // binary32/64. I don't know if there is a truly reliable way of detecting IEEE-754 binary |
476 | | // formats. I just did my best here. Note that in some cases |
477 | | // numeric_limits<Float>::is_iec559 may report false even if the internal representation is |
478 | | // IEEE-754 compatible. In such a case, the user can specialize this traits template and |
479 | | // remove this static sanity check in order to make Dragonbox work for Float. |
480 | | static_assert(detail::stdr::numeric_limits<Float>::is_iec559 && |
481 | | detail::stdr::numeric_limits<Float>::radix == 2 && |
482 | | (detail::physical_bits<Float>::value == 32 || detail::physical_bits<Float>::value == 64), |
483 | | "jkj::dragonbox: Float may not be of IEEE-754 binary32/binary64"); |
484 | | |
485 | | // Specifies the unsigned integer type to hold bitwise value of Float. |
486 | | using carrier_uint = |
487 | | typename detail::stdr::conditional<detail::physical_bits<Float>::value == 32, detail::stdr::uint_least32_t, |
488 | | detail::stdr::uint_least64_t>::type; |
489 | | |
490 | | // Specifies the floating-point format. |
491 | | using format = typename detail::stdr::conditional<detail::physical_bits<Float>::value == 32, ieee754_binary32, |
492 | | ieee754_binary64>::type; |
493 | | |
494 | | // Converts the floating-point type into the bit-carrier unsigned integer type. |
495 | | static GLZ_JKJ_CONSTEXPR20 carrier_uint float_to_carrier(Float x) noexcept |
496 | 0 | { |
497 | 0 | return detail::bit_cast<carrier_uint>(x); |
498 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::default_float_bit_carrier_conversion_traits<double>::float_to_carrier(double) Unexecuted instantiation: glz::jkj::dragonbox::default_float_bit_carrier_conversion_traits<float>::float_to_carrier(float) |
499 | | |
500 | | // Converts the bit-carrier unsigned integer type into the floating-point type. |
501 | | static GLZ_JKJ_CONSTEXPR20 Float carrier_to_float(carrier_uint x) noexcept |
502 | | { |
503 | | return detail::bit_cast<Float>(x); |
504 | | } |
505 | | }; |
506 | | |
507 | | // Convenient wrappers for floating-point traits classes. |
508 | | // In order to reduce the argument passing overhead, these classes should be as simple as |
509 | | // possible (e.g., no inheritance, no private non-static data member, etc.; this is an |
510 | | // unfortunate fact about common ABI convention). |
511 | | |
512 | | template <class FormatTraits> |
513 | | struct signed_significand_bits |
514 | | { |
515 | | using format_traits = FormatTraits; |
516 | | using carrier_uint = typename format_traits::carrier_uint; |
517 | | |
518 | | carrier_uint u; |
519 | | |
520 | | signed_significand_bits() = default; |
521 | | constexpr explicit signed_significand_bits(carrier_uint bit_pattern) noexcept : u{bit_pattern} {} |
522 | | |
523 | | // Shift the obtained signed significand bits to the left by 1 to remove the sign bit. |
524 | | constexpr carrier_uint remove_sign_bit_and_shift() const noexcept |
525 | 0 | { |
526 | 0 | return format_traits::remove_sign_bit_and_shift(u); |
527 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::remove_sign_bit_and_shift() const Unexecuted instantiation: glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::remove_sign_bit_and_shift() const |
528 | | |
529 | | constexpr bool is_positive() const noexcept { return format_traits::is_positive(u); } |
530 | | constexpr bool is_negative() const noexcept { return format_traits::is_negative(u); } |
531 | | constexpr bool has_all_zero_significand_bits() const noexcept |
532 | | { |
533 | | return format_traits::has_all_zero_significand_bits(u); |
534 | | } |
535 | | constexpr bool has_even_significand_bits() const noexcept |
536 | 0 | { |
537 | 0 | return format_traits::has_even_significand_bits(u); |
538 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::has_even_significand_bits() const Unexecuted instantiation: glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::has_even_significand_bits() const |
539 | | }; |
540 | | |
541 | | template <class FormatTraits> |
542 | | struct float_bits |
543 | | { |
544 | | using format_traits = FormatTraits; |
545 | | using carrier_uint = typename format_traits::carrier_uint; |
546 | | using exponent_int = typename format_traits::exponent_int; |
547 | | |
548 | | carrier_uint u; |
549 | | |
550 | | float_bits() = default; |
551 | | constexpr explicit float_bits(carrier_uint bit_pattern) noexcept : u{bit_pattern} {} |
552 | | |
553 | | // Extract exponent bits from a bit pattern. |
554 | | // The result must be aligned to the LSB so that there is no additional zero paddings |
555 | | // on the right. This function does not do bias adjustment. |
556 | | constexpr exponent_int extract_exponent_bits() const noexcept |
557 | 0 | { |
558 | 0 | return format_traits::extract_exponent_bits(u); |
559 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::float_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::extract_exponent_bits() const Unexecuted instantiation: glz::jkj::dragonbox::float_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::extract_exponent_bits() const |
560 | | |
561 | | // Extract significand bits from a bit pattern. |
562 | | // The result must be aligned to the LSB so that there is no additional zero paddings |
563 | | // on the right. The result does not contain the implicit bit. |
564 | | constexpr carrier_uint extract_significand_bits() const noexcept |
565 | | { |
566 | | return format_traits::extract_significand_bits(u); |
567 | | } |
568 | | |
569 | | // Remove the exponent bits and extract significand bits together with the sign bit. |
570 | | constexpr signed_significand_bits<format_traits> remove_exponent_bits() const noexcept |
571 | 0 | { |
572 | 0 | return signed_significand_bits<format_traits>(format_traits::remove_exponent_bits(u)); |
573 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::float_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::remove_exponent_bits() const Unexecuted instantiation: glz::jkj::dragonbox::float_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::remove_exponent_bits() const |
574 | | |
575 | | // Obtain the actual value of the binary exponent from the extracted exponent bits. |
576 | | static constexpr exponent_int binary_exponent(exponent_int exponent_bits) noexcept |
577 | | { |
578 | | return format_traits::binary_exponent(exponent_bits); |
579 | | } |
580 | | constexpr exponent_int binary_exponent() const noexcept { return binary_exponent(extract_exponent_bits()); } |
581 | | |
582 | | // Obtain the actual value of the binary exponent from the extracted significand bits |
583 | | // and exponent bits. |
584 | | static constexpr carrier_uint binary_significand(carrier_uint significand_bits, |
585 | | exponent_int exponent_bits) noexcept |
586 | | { |
587 | | return format_traits::binary_significand(significand_bits, exponent_bits); |
588 | | } |
589 | | constexpr carrier_uint binary_significand() const noexcept |
590 | | { |
591 | | return binary_significand(extract_significand_bits(), extract_exponent_bits()); |
592 | | } |
593 | | |
594 | | constexpr bool is_nonzero() const noexcept { return format_traits::is_nonzero(u); } |
595 | | constexpr bool is_positive() const noexcept { return format_traits::is_positive(u); } |
596 | | constexpr bool is_negative() const noexcept { return format_traits::is_negative(u); } |
597 | | constexpr bool is_finite(exponent_int exponent_bits) const noexcept |
598 | | { |
599 | | return format_traits::is_finite(exponent_bits); |
600 | | } |
601 | | constexpr bool is_finite() const noexcept { return format_traits::is_finite(extract_exponent_bits()); } |
602 | | constexpr bool has_even_significand_bits() const noexcept |
603 | | { |
604 | | return format_traits::has_even_significand_bits(u); |
605 | | } |
606 | | }; |
607 | | |
608 | | template <class Float, class ConversionTraits = default_float_bit_carrier_conversion_traits<Float>, |
609 | | class FormatTraits = |
610 | | ieee754_binary_traits<typename ConversionTraits::format, typename ConversionTraits::carrier_uint>> |
611 | | GLZ_JKJ_CONSTEXPR20 float_bits<FormatTraits> make_float_bits(Float x) noexcept |
612 | 0 | { |
613 | 0 | return float_bits<FormatTraits>(ConversionTraits::float_to_carrier(x)); |
614 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::float_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> > glz::jkj::dragonbox::make_float_bits<double, glz::jkj::dragonbox::default_float_bit_carrier_conversion_traits<double>, glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >(double) Unexecuted instantiation: glz::jkj::dragonbox::float_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> > glz::jkj::dragonbox::make_float_bits<float, glz::jkj::dragonbox::default_float_bit_carrier_conversion_traits<float>, glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >(float) |
615 | | |
616 | | namespace detail |
617 | | { |
618 | | //////////////////////////////////////////////////////////////////////////////////////// |
619 | | // Bit operation intrinsics. |
620 | | //////////////////////////////////////////////////////////////////////////////////////// |
621 | | |
622 | | namespace bits |
623 | | { |
624 | | // Most compilers should be able to optimize this into the ROR instruction. |
625 | | // n is assumed to be at most of bit_width bits. |
626 | | template <stdr::size_t bit_width, class UInt> |
627 | | GLZ_JKJ_CONSTEXPR14 UInt rotr(UInt n, unsigned int r) noexcept |
628 | 0 | { |
629 | 0 | static_assert(bit_width > 0, "jkj::dragonbox: rotation bit-width must be positive"); |
630 | 0 | static_assert(bit_width <= value_bits<UInt>::value, "jkj::dragonbox: rotation bit-width is too large"); |
631 | 0 | r &= (bit_width - 1); |
632 | 0 | return (n >> r) | (n << ((bit_width - r) & (bit_width - 1))); |
633 | 0 | } Unexecuted instantiation: unsigned int glz::jkj::dragonbox::detail::bits::rotr<32ul, unsigned int>(unsigned int, unsigned int) Unexecuted instantiation: unsigned long glz::jkj::dragonbox::detail::bits::rotr<64ul, unsigned long>(unsigned long, unsigned int) |
634 | | } |
635 | | |
636 | | //////////////////////////////////////////////////////////////////////////////////////// |
637 | | // Utilities for wide unsigned integer arithmetic. |
638 | | //////////////////////////////////////////////////////////////////////////////////////// |
639 | | |
640 | | namespace wuint |
641 | | { |
642 | | // Compilers might support built-in 128-bit integer types. However, it seems that |
643 | | // emulating them with a pair of 64-bit integers actually produces a better code, |
644 | | // so we avoid using those built-ins. That said, they are still useful for |
645 | | // implementing 64-bit x 64-bit -> 128-bit multiplication. |
646 | | |
647 | | // clang-format off |
648 | | #if defined(__SIZEOF_INT128__) |
649 | | // To silence "error: ISO C++ does not support '__int128' for 'type name' |
650 | | // [-Wpedantic]" |
651 | | #if defined(__GNUC__) |
652 | | __extension__ |
653 | | #endif |
654 | | using builtin_uint128_t = unsigned __int128; |
655 | | #endif |
656 | | // clang-format on |
657 | | |
658 | | struct uint128 |
659 | | { |
660 | | uint128() = default; |
661 | | |
662 | | stdr::uint_least64_t high_; |
663 | | stdr::uint_least64_t low_; |
664 | | |
665 | | constexpr uint128(stdr::uint_least64_t high, stdr::uint_least64_t low) noexcept : high_{high}, low_{low} |
666 | 0 | {} |
667 | | |
668 | 0 | constexpr stdr::uint_least64_t high() const noexcept { return high_; } |
669 | 0 | constexpr stdr::uint_least64_t low() const noexcept { return low_; } |
670 | | |
671 | | GLZ_JKJ_CONSTEXPR20 uint128& operator+=(stdr::uint_least64_t n) & noexcept |
672 | 0 | { |
673 | 0 | const auto generic_impl = [&] { |
674 | 0 | const auto sum = (low_ + n) & UINT64_C(0xffffffffffffffff); |
675 | 0 | high_ += (sum < low_ ? 1 : 0); |
676 | 0 | low_ = sum; |
677 | 0 | }; |
678 | 0 | // To suppress warning. |
679 | 0 | static_cast<void>(generic_impl); |
680 | 0 |
|
681 | 0 | GLZ_JKJ_IF_CONSTEXPR(value_bits<stdr::uint_least64_t>::value > 64) |
682 | 0 | { |
683 | 0 | generic_impl(); |
684 | 0 | return *this; |
685 | 0 | } |
686 | 0 |
|
687 | 0 | GLZ_JKJ_IF_CONSTEVAL |
688 | 0 | { |
689 | 0 | generic_impl(); |
690 | 0 | return *this; |
691 | 0 | } |
692 | 0 |
|
693 | 0 | // See https://github.com/fmtlib/fmt/pull/2985. |
694 | 0 | #if GLZ_JKJ_HAS_BUILTIN(__builtin_addcll) && !defined(__ibmxl__) |
695 | 0 | GLZ_JKJ_IF_CONSTEXPR(stdr::is_same<stdr::uint_least64_t, unsigned long long>::value) |
696 | 0 | { |
697 | 0 | unsigned long long carry{}; |
698 | 0 | low_ = stdr::uint_least64_t(__builtin_addcll(low_, n, 0, &carry)); |
699 | 0 | high_ = stdr::uint_least64_t(__builtin_addcll(high_, 0, carry, &carry)); |
700 | 0 | return *this; |
701 | 0 | } |
702 | 0 | #endif |
703 | 0 | #if GLZ_JKJ_HAS_BUILTIN(__builtin_addcl) && !defined(__ibmxl__) |
704 | 0 | GLZ_JKJ_IF_CONSTEXPR(stdr::is_same<stdr::uint_least64_t, unsigned long>::value) |
705 | 0 | { |
706 | 0 | unsigned long carry{}; |
707 | 0 | low_ = stdr::uint_least64_t( |
708 | 0 | __builtin_addcl(static_cast<unsigned long>(low_), static_cast<unsigned long>(n), 0, &carry)); |
709 | 0 | high_ = stdr::uint_least64_t(__builtin_addcl(static_cast<unsigned long>(high_), 0, carry, &carry)); |
710 | 0 | return *this; |
711 | 0 | } |
712 | 0 | #endif |
713 | 0 | #if GLZ_JKJ_HAS_BUILTIN(__builtin_addc) && !defined(__ibmxl__) |
714 | 0 | GLZ_JKJ_IF_CONSTEXPR(stdr::is_same<stdr::uint_least64_t, unsigned int>::value) |
715 | 0 | { |
716 | 0 | unsigned int carry{}; |
717 | 0 | low_ = stdr::uint_least64_t( |
718 | 0 | __builtin_addc(static_cast<unsigned int>(low_), static_cast<unsigned int>(n), 0, &carry)); |
719 | 0 | high_ = stdr::uint_least64_t(__builtin_addc(static_cast<unsigned int>(high_), 0, carry, &carry)); |
720 | 0 | return *this; |
721 | 0 | } |
722 | 0 | #endif |
723 | 0 |
|
724 | 0 | #if GLZ_JKJ_HAS_BUILTIN(__builtin_ia32_addcarry_u64) |
725 | 0 | // __builtin_ia32_addcarry_u64 is not documented, but it seems it takes unsigned |
726 | 0 | // long long arguments. |
727 | 0 | unsigned long long result{}; |
728 | 0 | const auto carry = __builtin_ia32_addcarry_u64(0, low_, n, &result); |
729 | 0 | low_ = stdr::uint_least64_t(result); |
730 | 0 | __builtin_ia32_addcarry_u64(carry, high_, 0, &result); |
731 | 0 | high_ = stdr::uint_least64_t(result); |
732 | 0 | #elif defined(_MSC_VER) && defined(_M_X64) |
733 | 0 | // On MSVC, uint_least64_t and __int64 must be unsigned long long; see |
734 | 0 | // https://learn.microsoft.com/en-us/cpp/c-runtime-library/standard-types |
735 | 0 | // and https://learn.microsoft.com/en-us/cpp/cpp/int8-int16-int32-int64. |
736 | 0 | static_assert(stdr::is_same<unsigned long long, stdr::uint_least64_t>::value, ""); |
737 | 0 | const auto carry = _addcarry_u64(0, low_, n, &low_); |
738 | 0 | _addcarry_u64(carry, high_, 0, &high_); |
739 | 0 | #elif defined(__INTEL_COMPILER) && (defined(_M_X64) || defined(__x86_64)) |
740 | 0 | // Cannot find any documentation on how things are defined, but hopefully this |
741 | 0 | // is always true... |
742 | 0 | static_assert(stdr::is_same<unsigned __int64, stdr::uint_least64_t>::value, ""); |
743 | 0 | const auto carry = _addcarry_u64(0, low_, n, &low_); |
744 | 0 | _addcarry_u64(carry, high_, 0, &high_); |
745 | 0 | #else |
746 | 0 | generic_impl(); |
747 | 0 | #endif |
748 | 0 | return *this; |
749 | 0 | } |
750 | | }; |
751 | | |
752 | | inline GLZ_JKJ_CONSTEXPR20 stdr::uint_least64_t umul64(stdr::uint_least32_t x, |
753 | | stdr::uint_least32_t y) noexcept |
754 | 0 | { |
755 | 0 | #if defined(_MSC_VER) && defined(_M_IX86) |
756 | 0 | GLZ_JKJ_IF_NOT_CONSTEVAL { return __emulu(x, y); } |
757 | 0 | #endif |
758 | 0 | return x * stdr::uint_least64_t(y); |
759 | 0 | } |
760 | | |
761 | | // Get 128-bit result of multiplication of two 64-bit unsigned integers. |
762 | | GLZ_JKJ_SAFEBUFFERS inline GLZ_JKJ_CONSTEXPR20 uint128 umul128(stdr::uint_least64_t x, |
763 | | stdr::uint_least64_t y) noexcept |
764 | 0 | { |
765 | 0 | const auto generic_impl = [=]() -> uint128 { |
766 | 0 | const auto a = stdr::uint_least32_t(x >> 32); |
767 | 0 | const auto b = stdr::uint_least32_t(x); |
768 | 0 | const auto c = stdr::uint_least32_t(y >> 32); |
769 | 0 | const auto d = stdr::uint_least32_t(y); |
770 | 0 |
|
771 | 0 | const auto ac = umul64(a, c); |
772 | 0 | const auto bc = umul64(b, c); |
773 | 0 | const auto ad = umul64(a, d); |
774 | 0 | const auto bd = umul64(b, d); |
775 | 0 |
|
776 | 0 | const auto intermediate = (bd >> 32) + stdr::uint_least32_t(ad) + stdr::uint_least32_t(bc); |
777 | 0 |
|
778 | 0 | return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32), |
779 | 0 | (intermediate << 32) + stdr::uint_least32_t(bd)}; |
780 | 0 | }; |
781 | 0 | // To silence warning. |
782 | 0 | static_cast<void>(generic_impl); |
783 | 0 |
|
784 | 0 | #if defined(__SIZEOF_INT128__) |
785 | 0 | const auto result = builtin_uint128_t(x) * builtin_uint128_t(y); |
786 | 0 | return {stdr::uint_least64_t(result >> 64), stdr::uint_least64_t(result)}; |
787 | 0 | #elif defined(_MSC_VER) && defined(_M_X64) |
788 | 0 | GLZ_JKJ_IF_CONSTEVAL |
789 | 0 | { |
790 | 0 | // This redundant variable is to workaround MSVC's codegen bug caused by the |
791 | 0 | // interaction of NRVO and intrinsics. |
792 | 0 | const auto result = generic_impl(); |
793 | 0 | return result; |
794 | 0 | } |
795 | 0 | uint128 result; |
796 | 0 | #if defined(__AVX2__) |
797 | 0 | result.low_ = _mulx_u64(x, y, &result.high_); |
798 | 0 | #else |
799 | 0 | result.low_ = _umul128(x, y, &result.high_); |
800 | 0 | #endif |
801 | 0 | return result; |
802 | 0 | #else |
803 | 0 | return generic_impl(); |
804 | 0 | #endif |
805 | 0 | } |
806 | | |
807 | | // Get high half of the 128-bit result of multiplication of two 64-bit unsigned |
808 | | // integers. |
809 | | GLZ_JKJ_SAFEBUFFERS inline GLZ_JKJ_CONSTEXPR20 stdr::uint_least64_t umul128_upper64( |
810 | | stdr::uint_least64_t x, stdr::uint_least64_t y) noexcept |
811 | 0 | { |
812 | 0 | const auto generic_impl = [=]() -> stdr::uint_least64_t { |
813 | 0 | const auto a = stdr::uint_least32_t(x >> 32); |
814 | 0 | const auto b = stdr::uint_least32_t(x); |
815 | 0 | const auto c = stdr::uint_least32_t(y >> 32); |
816 | 0 | const auto d = stdr::uint_least32_t(y); |
817 | 0 |
|
818 | 0 | const auto ac = umul64(a, c); |
819 | 0 | const auto bc = umul64(b, c); |
820 | 0 | const auto ad = umul64(a, d); |
821 | 0 | const auto bd = umul64(b, d); |
822 | 0 |
|
823 | 0 | const auto intermediate = (bd >> 32) + stdr::uint_least32_t(ad) + stdr::uint_least32_t(bc); |
824 | 0 |
|
825 | 0 | return ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32); |
826 | 0 | }; |
827 | 0 | // To silence warning. |
828 | 0 | static_cast<void>(generic_impl); |
829 | 0 |
|
830 | 0 | #if defined(__SIZEOF_INT128__) |
831 | 0 | const auto result = builtin_uint128_t(x) * builtin_uint128_t(y); |
832 | 0 | return stdr::uint_least64_t(result >> 64); |
833 | 0 | #elif defined(_MSC_VER) && defined(_M_X64) |
834 | 0 | GLZ_JKJ_IF_CONSTEVAL |
835 | 0 | { |
836 | 0 | // This redundant variable is to workaround MSVC's codegen bug caused by the |
837 | 0 | // interaction of NRVO and intrinsics. |
838 | 0 | const auto result = generic_impl(); |
839 | 0 | return result; |
840 | 0 | } |
841 | 0 | stdr::uint_least64_t result; |
842 | 0 | #if defined(__AVX2__) |
843 | 0 | _mulx_u64(x, y, &result); |
844 | 0 | #else |
845 | 0 | result = __umulh(x, y); |
846 | 0 | #endif |
847 | 0 | return result; |
848 | 0 | #else |
849 | 0 | return generic_impl(); |
850 | 0 | #endif |
851 | 0 | } |
852 | | |
853 | | // Get upper 128-bits of multiplication of a 64-bit unsigned integer and a 128-bit |
854 | | // unsigned integer. |
855 | | GLZ_JKJ_SAFEBUFFERS inline GLZ_JKJ_CONSTEXPR20 uint128 umul192_upper128(stdr::uint_least64_t x, |
856 | | uint128 y) noexcept |
857 | 0 | { |
858 | 0 | auto r = umul128(x, y.high()); |
859 | 0 | r += umul128_upper64(x, y.low()); |
860 | 0 | return r; |
861 | 0 | } |
862 | | |
863 | | // Get upper 64-bits of multiplication of a 32-bit unsigned integer and a 64-bit |
864 | | // unsigned integer. |
865 | | inline GLZ_JKJ_CONSTEXPR20 stdr::uint_least64_t umul96_upper64(stdr::uint_least32_t x, |
866 | | stdr::uint_least64_t y) noexcept |
867 | 0 | { |
868 | 0 | #if defined(__SIZEOF_INT128__) || (defined(_MSC_VER) && defined(_M_X64)) |
869 | 0 | return umul128_upper64(stdr::uint_least64_t(x) << 32, y); |
870 | 0 | #else |
871 | 0 | const auto yh = stdr::uint_least32_t(y >> 32); |
872 | 0 | const auto yl = stdr::uint_least32_t(y); |
873 | 0 |
|
874 | 0 | const auto xyh = umul64(x, yh); |
875 | 0 | const auto xyl = umul64(x, yl); |
876 | 0 |
|
877 | 0 | return xyh + (xyl >> 32); |
878 | 0 | #endif |
879 | 0 | } |
880 | | |
881 | | // Get lower 128-bits of multiplication of a 64-bit unsigned integer and a 128-bit |
882 | | // unsigned integer. |
883 | | GLZ_JKJ_SAFEBUFFERS inline GLZ_JKJ_CONSTEXPR20 uint128 umul192_lower128(stdr::uint_least64_t x, |
884 | | uint128 y) noexcept |
885 | 0 | { |
886 | 0 | const auto high = x * y.high(); |
887 | 0 | const auto high_low = umul128(x, y.low()); |
888 | 0 | return {(high + high_low.high()) & UINT64_C(0xffffffffffffffff), high_low.low()}; |
889 | 0 | } |
890 | | |
891 | | // Get lower 64-bits of multiplication of a 32-bit unsigned integer and a 64-bit |
892 | | // unsigned integer. |
893 | | constexpr stdr::uint_least64_t umul96_lower64(stdr::uint_least32_t x, stdr::uint_least64_t y) noexcept |
894 | 0 | { |
895 | 0 | return (x * y) & UINT64_C(0xffffffffffffffff); |
896 | 0 | } |
897 | | } |
898 | | |
899 | | //////////////////////////////////////////////////////////////////////////////////////// |
900 | | // Some simple utilities for constexpr computation. |
901 | | //////////////////////////////////////////////////////////////////////////////////////// |
902 | | |
903 | | template <int k, class Int> |
904 | | constexpr Int compute_power(Int a) noexcept |
905 | 0 | { |
906 | 0 | static_assert(k >= 0, ""); |
907 | 0 | #if GLZ_JKJ_HAS_CONSTEXPR14 |
908 | 0 | Int p = 1; |
909 | 0 | for (int i = 0; i < k; ++i) { |
910 | 0 | p *= a; |
911 | 0 | } |
912 | 0 | return p; |
913 | 0 | #else |
914 | 0 | return k == 0 ? 1 : k % 2 == 0 ? compute_power<k / 2, Int>(a * a) : a * compute_power<k / 2, Int>(a * a); |
915 | 0 | #endif |
916 | 0 | } Unexecuted instantiation: unsigned long glz::jkj::dragonbox::detail::compute_power<3, unsigned long>(unsigned long) Unexecuted instantiation: int glz::jkj::dragonbox::detail::compute_power<1, int>(int) Unexecuted instantiation: unsigned long glz::jkj::dragonbox::detail::compute_power<2, unsigned long>(unsigned long) Unexecuted instantiation: unsigned int glz::jkj::dragonbox::detail::compute_power<2, unsigned int>(unsigned int) Unexecuted instantiation: unsigned int glz::jkj::dragonbox::detail::compute_power<1, unsigned int>(unsigned int) |
917 | | |
918 | | template <int a, class UInt> |
919 | | constexpr int count_factors(UInt n) noexcept |
920 | 0 | { |
921 | 0 | static_assert(a > 1, ""); |
922 | 0 | #if GLZ_JKJ_HAS_CONSTEXPR14 |
923 | 0 | int c = 0; |
924 | 0 | while (n % a == 0) { |
925 | 0 | n /= a; |
926 | 0 | ++c; |
927 | 0 | } |
928 | 0 | return c; |
929 | 0 | #else |
930 | 0 | return n % a == 0 ? count_factors<a, UInt>(n / a) + 1 : 0; |
931 | 0 | #endif |
932 | 0 | } Unexecuted instantiation: int glz::jkj::dragonbox::detail::count_factors<5, unsigned long>(unsigned long) Unexecuted instantiation: int glz::jkj::dragonbox::detail::count_factors<5, unsigned int>(unsigned int) |
933 | | |
934 | | //////////////////////////////////////////////////////////////////////////////////////// |
935 | | // Utilities for fast/constexpr log computation. |
936 | | //////////////////////////////////////////////////////////////////////////////////////// |
937 | | |
938 | | namespace log |
939 | | { |
940 | | static_assert((stdr::int_fast32_t(-1) >> 1) == stdr::int_fast32_t(-1) && |
941 | | (stdr::int_fast16_t(-1) >> 1) == stdr::int_fast16_t(-1), |
942 | | "jkj::dragonbox: right-shift for signed integers must be arithmetic"); |
943 | | |
944 | | // For constexpr computation. |
945 | | // Returns -1 when n = 0. |
946 | | template <class UInt> |
947 | | constexpr int floor_log2(UInt n) noexcept |
948 | 0 | { |
949 | 0 | #if GLZ_JKJ_HAS_CONSTEXPR14 |
950 | 0 | int count = -1; |
951 | 0 | while (n != 0) { |
952 | 0 | ++count; |
953 | 0 | n >>= 1; |
954 | 0 | } |
955 | 0 | return count; |
956 | 0 | #else |
957 | 0 | return n == 0 ? -1 : floor_log2<UInt>(n / 2) + 1; |
958 | 0 | #endif |
959 | 0 | } |
960 | | |
961 | | template <template <stdr::size_t> class Info, stdr::int_least32_t min_exponent, |
962 | | stdr::int_least32_t max_exponent, stdr::size_t current_tier, |
963 | | stdr::int_least32_t supported_min_exponent = Info<current_tier>::min_exponent, |
964 | | stdr::int_least32_t supported_max_exponent = Info<current_tier>::max_exponent> |
965 | | constexpr bool is_in_range(int) noexcept |
966 | 0 | { |
967 | 0 | return min_exponent >= supported_min_exponent && max_exponent <= supported_max_exponent; |
968 | 0 | } Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -2620, 2620, 0ul, -102, 102>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -2620, 2620, 1ul, -425, 425>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -2620, 2620, 2ul, -2620, 2620>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -1233, 1233, 0ul, -15, 18>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -1233, 1233, 1ul, -58, 58>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -1233, 1233, 2ul, -1233, 1233>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -2985, 2936, 0ul, -75, 129>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -2985, 2936, 1ul, -424, 315>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -2985, 2936, 2ul, -2985, 2936>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -1074, 971, 0ul, -75, 129>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -1074, 971, 1ul, -424, 315>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -1074, 971, 2ul, -2985, 2936>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -292, 326, 0ul, -15, 18>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -292, 326, 1ul, -58, 58>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -292, 326, 2ul, -1233, 1233>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log5_pow2_minus_log5_3_info, -3543, 2427, 0ul, -3543, 2427>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log5_pow2_info, -1831, 1831, 0ul, -1831, 1831>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -1074, 971, 0ul, -102, 102>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -1074, 971, 1ul, -425, 425>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -1074, 971, 2ul, -2620, 2620>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -149, 104, 0ul, -75, 129>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -149, 104, 1ul, -424, 315>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -31, 46, 0ul, -15, 18>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -31, 46, 1ul, -58, 58>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -149, 104, 0ul, -102, 102>(int) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::log::is_in_range<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -149, 104, 1ul, -425, 425>(int) |
969 | | template <template <stdr::size_t> class Info, stdr::int_least32_t min_exponent, |
970 | | stdr::int_least32_t max_exponent, stdr::size_t current_tier> |
971 | | constexpr bool is_in_range(...) noexcept |
972 | | { |
973 | | // Supposed to be always false, but formally dependent on the template parameters. |
974 | | static_assert(min_exponent > max_exponent, "jkj::dragonbox: exponent range is too wide"); |
975 | | return false; |
976 | | } |
977 | | |
978 | | template <template <stdr::size_t> class Info, stdr::int_least32_t min_exponent, |
979 | | stdr::int_least32_t max_exponent, stdr::size_t current_tier = 0, |
980 | | bool = is_in_range<Info, min_exponent, max_exponent, current_tier>(0)> |
981 | | struct compute_impl; |
982 | | |
983 | | template <template <stdr::size_t> class Info, stdr::int_least32_t min_exponent, |
984 | | stdr::int_least32_t max_exponent, stdr::size_t current_tier> |
985 | | struct compute_impl<Info, min_exponent, max_exponent, current_tier, true> |
986 | | { |
987 | | using info = Info<current_tier>; |
988 | | using default_return_type = typename info::default_return_type; |
989 | | template <class ReturnType, class Int> |
990 | | static constexpr ReturnType compute(Int e) noexcept |
991 | 0 | { |
992 | 0 | #if GLZ_JKJ_HAS_CONSTEXPR14 |
993 | 0 | assert(min_exponent <= e && e <= max_exponent); |
994 | 0 | #endif |
995 | 0 | // The sign is irrelevant for the mathematical validity of the formula, but |
996 | 0 | // assuming positivity makes the overflow analysis simpler. |
997 | 0 | static_assert(info::multiply >= 0 && info::subtract >= 0, ""); |
998 | 0 | return static_cast<ReturnType>((e * info::multiply - info::subtract) >> info::shift); |
999 | 0 | } Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -2620, 2620, 2ul, true>::compute<long, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -1233, 1233, 2ul, true>::compute<long, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -2985, 2936, 2ul, true>::compute<long, int>(int) Unexecuted instantiation: int glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -1074, 971, 2ul, true>::compute<int, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -292, 326, 2ul, true>::compute<long, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log5_pow2_minus_log5_3_info, -3543, 2427, 0ul, true>::compute<long, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log5_pow2_info, -1831, 1831, 0ul, true>::compute<long, int>(int) Unexecuted instantiation: int glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -1074, 971, 2ul, true>::compute<int, int>(int) Unexecuted instantiation: int glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -149, 104, 1ul, true>::compute<int, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -31, 46, 1ul, true>::compute<long, int>(int) Unexecuted instantiation: int glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -149, 104, 1ul, true>::compute<int, int>(int) |
1000 | | }; |
1001 | | |
1002 | | template <template <stdr::size_t> class Info, stdr::int_least32_t min_exponent, |
1003 | | stdr::int_least32_t max_exponent, stdr::size_t current_tier> |
1004 | | struct compute_impl<Info, min_exponent, max_exponent, current_tier, false> |
1005 | | { |
1006 | | using next_tier = compute_impl<Info, min_exponent, max_exponent, current_tier + 1>; |
1007 | | using default_return_type = typename next_tier::default_return_type; |
1008 | | template <class ReturnType, class Int> |
1009 | | static constexpr ReturnType compute(Int e) noexcept |
1010 | 0 | { |
1011 | 0 | return next_tier::template compute<ReturnType>(e); |
1012 | 0 | } Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -2620, 2620, 1ul, false>::compute<long, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -2620, 2620, 0ul, false>::compute<long, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -1233, 1233, 1ul, false>::compute<long, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -1233, 1233, 0ul, false>::compute<long, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -2985, 2936, 1ul, false>::compute<long, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -2985, 2936, 0ul, false>::compute<long, int>(int) Unexecuted instantiation: int glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -1074, 971, 1ul, false>::compute<int, int>(int) Unexecuted instantiation: int glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -1074, 971, 0ul, false>::compute<int, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -292, 326, 1ul, false>::compute<long, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -292, 326, 0ul, false>::compute<long, int>(int) Unexecuted instantiation: int glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -1074, 971, 1ul, false>::compute<int, int>(int) Unexecuted instantiation: int glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -1074, 971, 0ul, false>::compute<int, int>(int) Unexecuted instantiation: int glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3_info, -149, 104, 0ul, false>::compute<int, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log2_pow10_info, -31, 46, 0ul, false>::compute<long, int>(int) Unexecuted instantiation: int glz::jkj::dragonbox::detail::log::compute_impl<glz::jkj::dragonbox::detail::log::floor_log10_pow2_info, -149, 104, 0ul, false>::compute<int, int>(int) |
1013 | | }; |
1014 | | |
1015 | | template <stdr::size_t tier> |
1016 | | struct floor_log10_pow2_info; |
1017 | | template <> |
1018 | | struct floor_log10_pow2_info<0> |
1019 | | { |
1020 | | using default_return_type = stdr::int_fast8_t; |
1021 | | static constexpr stdr::int_fast16_t multiply = 77; |
1022 | | static constexpr stdr::int_fast16_t subtract = 0; |
1023 | | static constexpr stdr::size_t shift = 8; |
1024 | | static constexpr stdr::int_least32_t min_exponent = -102; |
1025 | | static constexpr stdr::int_least32_t max_exponent = 102; |
1026 | | }; |
1027 | | template <> |
1028 | | struct floor_log10_pow2_info<1> |
1029 | | { |
1030 | | using default_return_type = stdr::int_fast8_t; |
1031 | | // 24-bits are enough in fact. |
1032 | | static constexpr stdr::int_fast32_t multiply = 1233; |
1033 | | static constexpr stdr::int_fast32_t subtract = 0; |
1034 | | static constexpr stdr::size_t shift = 12; |
1035 | | // Formula itself holds on [-680,680]; [-425,425] is to ensure that the output is |
1036 | | // within [-127,127]. |
1037 | | static constexpr stdr::int_least32_t min_exponent = -425; |
1038 | | static constexpr stdr::int_least32_t max_exponent = 425; |
1039 | | }; |
1040 | | template <> |
1041 | | struct floor_log10_pow2_info<2> |
1042 | | { |
1043 | | using default_return_type = stdr::int_fast16_t; |
1044 | | static constexpr stdr::int_fast32_t multiply = INT32_C(315653); |
1045 | | static constexpr stdr::int_fast32_t subtract = 0; |
1046 | | static constexpr stdr::size_t shift = 20; |
1047 | | static constexpr stdr::int_least32_t min_exponent = -2620; |
1048 | | static constexpr stdr::int_least32_t max_exponent = 2620; |
1049 | | }; |
1050 | | template <stdr::int_least32_t min_exponent = -2620, stdr::int_least32_t max_exponent = 2620, |
1051 | | class ReturnType = |
1052 | | typename compute_impl<floor_log10_pow2_info, min_exponent, max_exponent>::default_return_type, |
1053 | | class Int> |
1054 | | constexpr ReturnType floor_log10_pow2(Int e) noexcept |
1055 | 0 | { |
1056 | 0 | return compute_impl<floor_log10_pow2_info, min_exponent, max_exponent>::template compute<ReturnType>(e); |
1057 | 0 | } Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::floor_log10_pow2<-2620, 2620, long, int>(int) Unexecuted instantiation: int glz::jkj::dragonbox::detail::log::floor_log10_pow2<-1074, 971, int, int>(int) Unexecuted instantiation: int glz::jkj::dragonbox::detail::log::floor_log10_pow2<-149, 104, int, int>(int) |
1058 | | |
1059 | | template <stdr::size_t tier> |
1060 | | struct floor_log2_pow10_info; |
1061 | | template <> |
1062 | | struct floor_log2_pow10_info<0> |
1063 | | { |
1064 | | using default_return_type = stdr::int_fast8_t; |
1065 | | static constexpr stdr::int_fast16_t multiply = 53; |
1066 | | static constexpr stdr::int_fast16_t subtract = 0; |
1067 | | static constexpr stdr::size_t shift = 4; |
1068 | | static constexpr stdr::int_least32_t min_exponent = -15; |
1069 | | static constexpr stdr::int_least32_t max_exponent = 18; |
1070 | | }; |
1071 | | template <> |
1072 | | struct floor_log2_pow10_info<1> |
1073 | | { |
1074 | | using default_return_type = stdr::int_fast16_t; |
1075 | | // 24-bits are enough in fact. |
1076 | | static constexpr stdr::int_fast32_t multiply = 1701; |
1077 | | static constexpr stdr::int_fast32_t subtract = 0; |
1078 | | static constexpr stdr::size_t shift = 9; |
1079 | | static constexpr stdr::int_least32_t min_exponent = -58; |
1080 | | static constexpr stdr::int_least32_t max_exponent = 58; |
1081 | | }; |
1082 | | template <> |
1083 | | struct floor_log2_pow10_info<2> |
1084 | | { |
1085 | | using default_return_type = stdr::int_fast16_t; |
1086 | | static constexpr stdr::int_fast32_t multiply = INT32_C(1741647); |
1087 | | static constexpr stdr::int_fast32_t subtract = 0; |
1088 | | static constexpr stdr::size_t shift = 19; |
1089 | | // Formula itself holds on [-4003,4003]; [-1233,1233] is to ensure no overflow. |
1090 | | static constexpr stdr::int_least32_t min_exponent = -1233; |
1091 | | static constexpr stdr::int_least32_t max_exponent = 1233; |
1092 | | }; |
1093 | | template <stdr::int_least32_t min_exponent = -1233, stdr::int_least32_t max_exponent = 1233, |
1094 | | class ReturnType = |
1095 | | typename compute_impl<floor_log2_pow10_info, min_exponent, max_exponent>::default_return_type, |
1096 | | class Int> |
1097 | | constexpr ReturnType floor_log2_pow10(Int e) noexcept |
1098 | 0 | { |
1099 | 0 | return compute_impl<floor_log2_pow10_info, min_exponent, max_exponent>::template compute<ReturnType>(e); |
1100 | 0 | } Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::floor_log2_pow10<-1233, 1233, long, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::floor_log2_pow10<-292, 326, long, int>(int) Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::floor_log2_pow10<-31, 46, long, int>(int) |
1101 | | |
1102 | | template <stdr::size_t tier> |
1103 | | struct floor_log10_pow2_minus_log10_4_over_3_info; |
1104 | | template <> |
1105 | | struct floor_log10_pow2_minus_log10_4_over_3_info<0> |
1106 | | { |
1107 | | using default_return_type = stdr::int_fast8_t; |
1108 | | static constexpr stdr::int_fast16_t multiply = 77; |
1109 | | static constexpr stdr::int_fast16_t subtract = 31; |
1110 | | static constexpr stdr::size_t shift = 8; |
1111 | | static constexpr stdr::int_least32_t min_exponent = -75; |
1112 | | static constexpr stdr::int_least32_t max_exponent = 129; |
1113 | | }; |
1114 | | template <> |
1115 | | struct floor_log10_pow2_minus_log10_4_over_3_info<1> |
1116 | | { |
1117 | | using default_return_type = stdr::int_fast8_t; |
1118 | | // 24-bits are enough in fact. |
1119 | | static constexpr stdr::int_fast32_t multiply = 19728; |
1120 | | static constexpr stdr::int_fast32_t subtract = 8241; |
1121 | | static constexpr stdr::size_t shift = 16; |
1122 | | // Formula itself holds on [-849,315]; [-424,315] is to ensure that the output is |
1123 | | // within [-127,127]. |
1124 | | static constexpr stdr::int_least32_t min_exponent = -424; |
1125 | | static constexpr stdr::int_least32_t max_exponent = 315; |
1126 | | }; |
1127 | | template <> |
1128 | | struct floor_log10_pow2_minus_log10_4_over_3_info<2> |
1129 | | { |
1130 | | using default_return_type = stdr::int_fast16_t; |
1131 | | static constexpr stdr::int_fast32_t multiply = INT32_C(631305); |
1132 | | static constexpr stdr::int_fast32_t subtract = INT32_C(261663); |
1133 | | static constexpr stdr::size_t shift = 21; |
1134 | | static constexpr stdr::int_least32_t min_exponent = -2985; |
1135 | | static constexpr stdr::int_least32_t max_exponent = 2936; |
1136 | | }; |
1137 | | template <stdr::int_least32_t min_exponent = -2985, stdr::int_least32_t max_exponent = 2936, |
1138 | | class ReturnType = typename compute_impl<floor_log10_pow2_minus_log10_4_over_3_info, min_exponent, |
1139 | | max_exponent>::default_return_type, |
1140 | | class Int> |
1141 | | constexpr ReturnType floor_log10_pow2_minus_log10_4_over_3(Int e) noexcept |
1142 | 0 | { |
1143 | 0 | return compute_impl<floor_log10_pow2_minus_log10_4_over_3_info, min_exponent, |
1144 | 0 | max_exponent>::template compute<ReturnType>(e); |
1145 | 0 | } Unexecuted instantiation: long glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3<-2985, 2936, long, int>(int) Unexecuted instantiation: int glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3<-1074, 971, int, int>(int) Unexecuted instantiation: int glz::jkj::dragonbox::detail::log::floor_log10_pow2_minus_log10_4_over_3<-149, 104, int, int>(int) |
1146 | | |
1147 | | template <stdr::size_t tier> |
1148 | | struct floor_log5_pow2_info; |
1149 | | template <> |
1150 | | struct floor_log5_pow2_info<0> |
1151 | | { |
1152 | | using default_return_type = stdr::int_fast32_t; |
1153 | | static constexpr stdr::int_fast32_t multiply = INT32_C(225799); |
1154 | | static constexpr stdr::int_fast32_t subtract = 0; |
1155 | | static constexpr stdr::size_t shift = 19; |
1156 | | static constexpr stdr::int_least32_t min_exponent = -1831; |
1157 | | static constexpr stdr::int_least32_t max_exponent = 1831; |
1158 | | }; |
1159 | | template <stdr::int_least32_t min_exponent = -1831, stdr::int_least32_t max_exponent = 1831, |
1160 | | class ReturnType = |
1161 | | typename compute_impl<floor_log5_pow2_info, min_exponent, max_exponent>::default_return_type, |
1162 | | class Int> |
1163 | | constexpr ReturnType floor_log5_pow2(Int e) noexcept |
1164 | 0 | { |
1165 | 0 | return compute_impl<floor_log5_pow2_info, min_exponent, max_exponent>::template compute<ReturnType>(e); |
1166 | 0 | } |
1167 | | |
1168 | | template <stdr::size_t tier> |
1169 | | struct floor_log5_pow2_minus_log5_3_info; |
1170 | | template <> |
1171 | | struct floor_log5_pow2_minus_log5_3_info<0> |
1172 | | { |
1173 | | using default_return_type = stdr::int_fast32_t; |
1174 | | static constexpr stdr::int_fast32_t multiply = INT32_C(451597); |
1175 | | static constexpr stdr::int_fast32_t subtract = INT32_C(715764); |
1176 | | static constexpr stdr::size_t shift = 20; |
1177 | | static constexpr stdr::int_least32_t min_exponent = -3543; |
1178 | | static constexpr stdr::int_least32_t max_exponent = 2427; |
1179 | | }; |
1180 | | template <stdr::int_least32_t min_exponent = -3543, stdr::int_least32_t max_exponent = 2427, |
1181 | | class ReturnType = typename compute_impl<floor_log5_pow2_minus_log5_3_info, min_exponent, |
1182 | | max_exponent>::default_return_type, |
1183 | | class Int> |
1184 | | constexpr ReturnType floor_log5_pow2_minus_log5_3(Int e) noexcept |
1185 | 0 | { |
1186 | 0 | return compute_impl<floor_log5_pow2_minus_log5_3_info, min_exponent, |
1187 | 0 | max_exponent>::template compute<ReturnType>(e); |
1188 | 0 | } |
1189 | | } |
1190 | | |
1191 | | //////////////////////////////////////////////////////////////////////////////////////// |
1192 | | // Utilities for fast divisibility tests. |
1193 | | //////////////////////////////////////////////////////////////////////////////////////// |
1194 | | |
1195 | | namespace div |
1196 | | { |
1197 | | // Replace n by floor(n / 10^N). |
1198 | | // Returns true if and only if n is divisible by 10^N. |
1199 | | // Precondition: n <= 10^(N+1) |
1200 | | // !!It takes an in-out parameter!! |
1201 | | template <int N, class UInt> |
1202 | | struct divide_by_pow10_info; |
1203 | | |
1204 | | template <class UInt> |
1205 | | struct divide_by_pow10_info<1, UInt> |
1206 | | { |
1207 | | static constexpr stdr::uint_fast32_t magic_number = 6554; |
1208 | | static constexpr int shift_amount = 16; |
1209 | | }; |
1210 | | |
1211 | | template <> |
1212 | | struct divide_by_pow10_info<1, stdr::uint_least8_t> |
1213 | | { |
1214 | | static constexpr stdr::uint_fast16_t magic_number = 103; |
1215 | | static constexpr int shift_amount = 10; |
1216 | | }; |
1217 | | |
1218 | | template <> |
1219 | | struct divide_by_pow10_info<1, stdr::uint_least16_t> |
1220 | | { |
1221 | | static constexpr stdr::uint_fast16_t magic_number = 103; |
1222 | | static constexpr int shift_amount = 10; |
1223 | | }; |
1224 | | |
1225 | | template <class UInt> |
1226 | | struct divide_by_pow10_info<2, UInt> |
1227 | | { |
1228 | | static constexpr stdr::uint_fast32_t magic_number = 656; |
1229 | | static constexpr int shift_amount = 16; |
1230 | | }; |
1231 | | |
1232 | | template <> |
1233 | | struct divide_by_pow10_info<2, stdr::uint_least16_t> |
1234 | | { |
1235 | | static constexpr stdr::uint_fast32_t magic_number = 41; |
1236 | | static constexpr int shift_amount = 12; |
1237 | | }; |
1238 | | |
1239 | | template <int N, class UInt> |
1240 | | GLZ_JKJ_CONSTEXPR14 bool check_divisibility_and_divide_by_pow10(UInt& n) noexcept |
1241 | 0 | { |
1242 | 0 | // Make sure the computation for max_n does not overflow. |
1243 | 0 | static_assert(N + 1 <= log::floor_log10_pow2(int(value_bits<UInt>::value)), ""); |
1244 | 0 | assert(n <= compute_power<N + 1>(UInt(10))); |
1245 | 0 |
|
1246 | 0 | using info = divide_by_pow10_info<N, UInt>; |
1247 | 0 | using intermediate_type = decltype(info::magic_number); |
1248 | 0 | const auto prod = intermediate_type(n * info::magic_number); |
1249 | 0 |
|
1250 | 0 | constexpr auto mask = intermediate_type((intermediate_type(1) << info::shift_amount) - 1); |
1251 | 0 | const bool result = ((prod & mask) < info::magic_number); |
1252 | 0 |
|
1253 | 0 | n = UInt(prod >> info::shift_amount); |
1254 | 0 | return result; |
1255 | 0 | } Unexecuted instantiation: bool glz::jkj::dragonbox::detail::div::check_divisibility_and_divide_by_pow10<2, unsigned long>(unsigned long&) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::div::check_divisibility_and_divide_by_pow10<1, unsigned int>(unsigned int&) |
1256 | | |
1257 | | // Compute floor(n / 10^N) for small n and N. |
1258 | | // Precondition: n <= 10^(N+1) |
1259 | | template <int N, class UInt> |
1260 | | GLZ_JKJ_CONSTEXPR14 UInt small_division_by_pow10(UInt n) noexcept |
1261 | | { |
1262 | | // Make sure the computation for max_n does not overflow. |
1263 | | static_assert(N + 1 <= log::floor_log10_pow2(int(value_bits<UInt>::value)), ""); |
1264 | | assert(n <= compute_power<N + 1>(UInt(10))); |
1265 | | |
1266 | | return UInt((n * divide_by_pow10_info<N, UInt>::magic_number) >> |
1267 | | divide_by_pow10_info<N, UInt>::shift_amount); |
1268 | | } |
1269 | | |
1270 | | // Compute floor(n / 10^N) for small N. |
1271 | | // Precondition: n <= n_max |
1272 | | template <int N, class UInt, UInt n_max> |
1273 | | GLZ_JKJ_CONSTEXPR20 UInt divide_by_pow10(UInt n) noexcept |
1274 | 0 | { |
1275 | 0 | static_assert(N >= 0, ""); |
1276 | 0 |
|
1277 | 0 | // Specialize for 32-bit division by 10. |
1278 | 0 | // Without the bound on n_max (which compilers these days never leverage), the |
1279 | 0 | // minimum needed amount of shift is larger than 32. Hence, this may generate better |
1280 | 0 | // code for 32-bit or smaller architectures. Even for 64-bit architectures, it seems |
1281 | 0 | // compilers tend to generate mov + mul instead of a single imul for an unknown |
1282 | 0 | // reason if we just write n / 10. |
1283 | 0 | GLZ_JKJ_IF_CONSTEXPR(stdr::is_same<UInt, stdr::uint_least32_t>::value && N == 1 && |
1284 | 0 | n_max <= UINT32_C(1073741828)) |
1285 | 0 | { |
1286 | 0 | return UInt(wuint::umul64(n, UINT32_C(429496730)) >> 32); |
1287 | 0 | } |
1288 | 0 | // Specialize for 64-bit division by 10. |
1289 | 0 | // Without the bound on n_max (which compilers these days never leverage), the |
1290 | 0 | // minimum needed amount of shift is larger than 64. |
1291 | 0 | else GLZ_JKJ_IF_CONSTEXPR(stdr::is_same<UInt, stdr::uint_least64_t>::value && N == 1 && |
1292 | 0 | n_max <= UINT64_C(4611686018427387908)) |
1293 | 0 | { |
1294 | 0 | return UInt(wuint::umul128_upper64(n, UINT64_C(1844674407370955162))); |
1295 | 0 | } |
1296 | 0 | // Specialize for 32-bit division by 100. |
1297 | 0 | // It seems compilers tend to generate mov + mul instead of a single imul for an |
1298 | 0 | // unknown reason if we just write n / 100. |
1299 | 0 | else GLZ_JKJ_IF_CONSTEXPR(stdr::is_same<UInt, stdr::uint_least32_t>::value && N == 2) |
1300 | 0 | { |
1301 | 0 | return UInt(wuint::umul64(n, UINT32_C(1374389535)) >> 37); |
1302 | 0 | } |
1303 | 0 | // Specialize for 64-bit division by 1000. |
1304 | 0 | // Without the bound on n_max (which compilers these days never leverage), the |
1305 | 0 | // smallest magic number for this computation does not fit into 64-bits. |
1306 | 0 | else GLZ_JKJ_IF_CONSTEXPR(stdr::is_same<UInt, stdr::uint_least64_t>::value && N == 3 && |
1307 | 0 | n_max <= UINT64_C(15534100272597517998)) |
1308 | 0 | { |
1309 | 0 | return UInt(wuint::umul128_upper64(n, UINT64_C(4722366482869645214)) >> 8); |
1310 | 0 | } |
1311 | 0 | else |
1312 | 0 | { |
1313 | 0 | constexpr auto divisor = compute_power<N>(UInt(10)); |
1314 | 0 | return n / divisor; |
1315 | 0 | } |
1316 | 0 | } Unexecuted instantiation: _ZN3glz3jkj9dragonbox6detail3div15divide_by_pow10ILi1EmTnT0_Lm60047995031606640EEES5_S5_ Unexecuted instantiation: _ZN3glz3jkj9dragonbox6detail3div15divide_by_pow10ILi3EmTnT0_Lm9007199254740991999EEES5_S5_ Unexecuted instantiation: _ZN3glz3jkj9dragonbox6detail3div15divide_by_pow10ILi1EjTnT0_Lj111848120EEES5_S5_ Unexecuted instantiation: _ZN3glz3jkj9dragonbox6detail3div15divide_by_pow10ILi2EjTnT0_Lj1677721599EEES5_S5_ |
1317 | | } |
1318 | | } |
1319 | | |
1320 | | //////////////////////////////////////////////////////////////////////////////////////// |
1321 | | // Return types for the main interface function. |
1322 | | //////////////////////////////////////////////////////////////////////////////////////// |
1323 | | |
1324 | | template <class SignificandType, class ExponentType, bool is_signed, bool trailing_zero_flag> |
1325 | | struct decimal_fp; |
1326 | | |
1327 | | template <class SignificandType, class ExponentType> |
1328 | | struct decimal_fp<SignificandType, ExponentType, false, false> |
1329 | | { |
1330 | | SignificandType significand; |
1331 | | ExponentType exponent; |
1332 | | }; |
1333 | | |
1334 | | template <class SignificandType, class ExponentType> |
1335 | | struct decimal_fp<SignificandType, ExponentType, true, false> |
1336 | | { |
1337 | | SignificandType significand; |
1338 | | ExponentType exponent; |
1339 | | bool is_negative; |
1340 | | }; |
1341 | | |
1342 | | template <class SignificandType, class ExponentType> |
1343 | | struct decimal_fp<SignificandType, ExponentType, false, true> |
1344 | | { |
1345 | | SignificandType significand; |
1346 | | ExponentType exponent; |
1347 | | bool may_have_trailing_zeros; |
1348 | | }; |
1349 | | |
1350 | | template <class SignificandType, class ExponentType> |
1351 | | struct decimal_fp<SignificandType, ExponentType, true, true> |
1352 | | { |
1353 | | SignificandType significand; |
1354 | | ExponentType exponent; |
1355 | | bool may_have_trailing_zeros; |
1356 | | bool is_negative; |
1357 | | }; |
1358 | | |
1359 | | template <class SignificandType, class ExponentType, bool trailing_zero_flag = false> |
1360 | | using unsigned_decimal_fp = decimal_fp<SignificandType, ExponentType, false, trailing_zero_flag>; |
1361 | | |
1362 | | template <class SignificandType, class ExponentType, bool trailing_zero_flag = false> |
1363 | | using signed_decimal_fp = decimal_fp<SignificandType, ExponentType, true, trailing_zero_flag>; |
1364 | | |
1365 | | template <class SignificandType, class ExponentType> |
1366 | | constexpr signed_decimal_fp<SignificandType, ExponentType, false> add_sign_to_unsigned_decimal_fp( |
1367 | | bool is_negative, unsigned_decimal_fp<SignificandType, ExponentType, false> r) noexcept |
1368 | | { |
1369 | | return {r.significand, r.exponent, is_negative}; |
1370 | | } |
1371 | | |
1372 | | template <class SignificandType, class ExponentType> |
1373 | | constexpr signed_decimal_fp<SignificandType, ExponentType, true> add_sign_to_unsigned_decimal_fp( |
1374 | | bool is_negative, unsigned_decimal_fp<SignificandType, ExponentType, true> r) noexcept |
1375 | | { |
1376 | | return {r.significand, r.exponent, r.may_have_trailing_zeros, is_negative}; |
1377 | | } |
1378 | | |
1379 | | namespace detail |
1380 | | { |
1381 | | template <class UnsignedDecimalFp> |
1382 | | struct unsigned_decimal_fp_to_signed; |
1383 | | |
1384 | | template <class SignificandType, class ExponentType, bool trailing_zero_flag> |
1385 | | struct unsigned_decimal_fp_to_signed<unsigned_decimal_fp<SignificandType, ExponentType, trailing_zero_flag>> |
1386 | | { |
1387 | | using type = signed_decimal_fp<SignificandType, ExponentType, trailing_zero_flag>; |
1388 | | }; |
1389 | | |
1390 | | template <class UnsignedDecimalFp> |
1391 | | using unsigned_decimal_fp_to_signed_t = typename unsigned_decimal_fp_to_signed<UnsignedDecimalFp>::type; |
1392 | | } |
1393 | | |
1394 | | //////////////////////////////////////////////////////////////////////////////////////// |
1395 | | // Computed cache entries. |
1396 | | //////////////////////////////////////////////////////////////////////////////////////// |
1397 | | |
1398 | | template <class FloatFormat, class Dummy = void> |
1399 | | struct cache_holder; |
1400 | | |
1401 | | template <class Dummy> |
1402 | | struct cache_holder<ieee754_binary32, Dummy> |
1403 | | { |
1404 | | using cache_entry_type = detail::stdr::uint_least64_t; |
1405 | | static constexpr int cache_bits = 64; |
1406 | | static constexpr int min_k = -31; |
1407 | | static constexpr int max_k = 46; |
1408 | | static constexpr detail::array<cache_entry_type, detail::stdr::size_t(max_k - min_k + 1)> cache |
1409 | | GLZ_JKJ_STATIC_DATA_SECTION = { |
1410 | | {UINT64_C(0x81ceb32c4b43fcf5), UINT64_C(0xa2425ff75e14fc32), UINT64_C(0xcad2f7f5359a3b3f), |
1411 | | UINT64_C(0xfd87b5f28300ca0e), UINT64_C(0x9e74d1b791e07e49), UINT64_C(0xc612062576589ddb), |
1412 | | UINT64_C(0xf79687aed3eec552), UINT64_C(0x9abe14cd44753b53), UINT64_C(0xc16d9a0095928a28), |
1413 | | UINT64_C(0xf1c90080baf72cb2), UINT64_C(0x971da05074da7bef), UINT64_C(0xbce5086492111aeb), |
1414 | | UINT64_C(0xec1e4a7db69561a6), UINT64_C(0x9392ee8e921d5d08), UINT64_C(0xb877aa3236a4b44a), |
1415 | | UINT64_C(0xe69594bec44de15c), UINT64_C(0x901d7cf73ab0acda), UINT64_C(0xb424dc35095cd810), |
1416 | | UINT64_C(0xe12e13424bb40e14), UINT64_C(0x8cbccc096f5088cc), UINT64_C(0xafebff0bcb24aaff), |
1417 | | UINT64_C(0xdbe6fecebdedd5bf), UINT64_C(0x89705f4136b4a598), UINT64_C(0xabcc77118461cefd), |
1418 | | UINT64_C(0xd6bf94d5e57a42bd), UINT64_C(0x8637bd05af6c69b6), UINT64_C(0xa7c5ac471b478424), |
1419 | | UINT64_C(0xd1b71758e219652c), UINT64_C(0x83126e978d4fdf3c), UINT64_C(0xa3d70a3d70a3d70b), |
1420 | | UINT64_C(0xcccccccccccccccd), UINT64_C(0x8000000000000000), UINT64_C(0xa000000000000000), |
1421 | | UINT64_C(0xc800000000000000), UINT64_C(0xfa00000000000000), UINT64_C(0x9c40000000000000), |
1422 | | UINT64_C(0xc350000000000000), UINT64_C(0xf424000000000000), UINT64_C(0x9896800000000000), |
1423 | | UINT64_C(0xbebc200000000000), UINT64_C(0xee6b280000000000), UINT64_C(0x9502f90000000000), |
1424 | | UINT64_C(0xba43b74000000000), UINT64_C(0xe8d4a51000000000), UINT64_C(0x9184e72a00000000), |
1425 | | UINT64_C(0xb5e620f480000000), UINT64_C(0xe35fa931a0000000), UINT64_C(0x8e1bc9bf04000000), |
1426 | | UINT64_C(0xb1a2bc2ec5000000), UINT64_C(0xde0b6b3a76400000), UINT64_C(0x8ac7230489e80000), |
1427 | | UINT64_C(0xad78ebc5ac620000), UINT64_C(0xd8d726b7177a8000), UINT64_C(0x878678326eac9000), |
1428 | | UINT64_C(0xa968163f0a57b400), UINT64_C(0xd3c21bcecceda100), UINT64_C(0x84595161401484a0), |
1429 | | UINT64_C(0xa56fa5b99019a5c8), UINT64_C(0xcecb8f27f4200f3a), UINT64_C(0x813f3978f8940985), |
1430 | | UINT64_C(0xa18f07d736b90be6), UINT64_C(0xc9f2c9cd04674edf), UINT64_C(0xfc6f7c4045812297), |
1431 | | UINT64_C(0x9dc5ada82b70b59e), UINT64_C(0xc5371912364ce306), UINT64_C(0xf684df56c3e01bc7), |
1432 | | UINT64_C(0x9a130b963a6c115d), UINT64_C(0xc097ce7bc90715b4), UINT64_C(0xf0bdc21abb48db21), |
1433 | | UINT64_C(0x96769950b50d88f5), UINT64_C(0xbc143fa4e250eb32), UINT64_C(0xeb194f8e1ae525fe), |
1434 | | UINT64_C(0x92efd1b8d0cf37bf), UINT64_C(0xb7abc627050305ae), UINT64_C(0xe596b7b0c643c71a), |
1435 | | UINT64_C(0x8f7e32ce7bea5c70), UINT64_C(0xb35dbf821ae4f38c), UINT64_C(0xe0352f62a19e306f)}}; |
1436 | | }; |
1437 | | #if !GLZ_JKJ_HAS_INLINE_VARIABLE |
1438 | | // decltype(...) should not depend on Dummy; see |
1439 | | // https://stackoverflow.com/questions/76438400/decltype-on-static-variable-in-template-class. |
1440 | | template <class Dummy> |
1441 | | constexpr decltype(cache_holder<ieee754_binary32>::cache) cache_holder<ieee754_binary32, Dummy>::cache; |
1442 | | #endif |
1443 | | |
1444 | | template <class Dummy> |
1445 | | struct cache_holder<ieee754_binary64, Dummy> |
1446 | | { |
1447 | | using cache_entry_type = detail::wuint::uint128; |
1448 | | static constexpr int cache_bits = 128; |
1449 | | static constexpr int min_k = -292; |
1450 | | static constexpr int max_k = 326; |
1451 | | static constexpr detail::array<cache_entry_type, detail::stdr::size_t(max_k - min_k + 1)> cache |
1452 | | GLZ_JKJ_STATIC_DATA_SECTION = {{{UINT64_C(0xff77b1fcbebcdc4f), UINT64_C(0x25e8e89c13bb0f7b)}, |
1453 | | {UINT64_C(0x9faacf3df73609b1), UINT64_C(0x77b191618c54e9ad)}, |
1454 | | {UINT64_C(0xc795830d75038c1d), UINT64_C(0xd59df5b9ef6a2418)}, |
1455 | | {UINT64_C(0xf97ae3d0d2446f25), UINT64_C(0x4b0573286b44ad1e)}, |
1456 | | {UINT64_C(0x9becce62836ac577), UINT64_C(0x4ee367f9430aec33)}, |
1457 | | {UINT64_C(0xc2e801fb244576d5), UINT64_C(0x229c41f793cda740)}, |
1458 | | {UINT64_C(0xf3a20279ed56d48a), UINT64_C(0x6b43527578c11110)}, |
1459 | | {UINT64_C(0x9845418c345644d6), UINT64_C(0x830a13896b78aaaa)}, |
1460 | | {UINT64_C(0xbe5691ef416bd60c), UINT64_C(0x23cc986bc656d554)}, |
1461 | | {UINT64_C(0xedec366b11c6cb8f), UINT64_C(0x2cbfbe86b7ec8aa9)}, |
1462 | | {UINT64_C(0x94b3a202eb1c3f39), UINT64_C(0x7bf7d71432f3d6aa)}, |
1463 | | {UINT64_C(0xb9e08a83a5e34f07), UINT64_C(0xdaf5ccd93fb0cc54)}, |
1464 | | {UINT64_C(0xe858ad248f5c22c9), UINT64_C(0xd1b3400f8f9cff69)}, |
1465 | | {UINT64_C(0x91376c36d99995be), UINT64_C(0x23100809b9c21fa2)}, |
1466 | | {UINT64_C(0xb58547448ffffb2d), UINT64_C(0xabd40a0c2832a78b)}, |
1467 | | {UINT64_C(0xe2e69915b3fff9f9), UINT64_C(0x16c90c8f323f516d)}, |
1468 | | {UINT64_C(0x8dd01fad907ffc3b), UINT64_C(0xae3da7d97f6792e4)}, |
1469 | | {UINT64_C(0xb1442798f49ffb4a), UINT64_C(0x99cd11cfdf41779d)}, |
1470 | | {UINT64_C(0xdd95317f31c7fa1d), UINT64_C(0x40405643d711d584)}, |
1471 | | {UINT64_C(0x8a7d3eef7f1cfc52), UINT64_C(0x482835ea666b2573)}, |
1472 | | {UINT64_C(0xad1c8eab5ee43b66), UINT64_C(0xda3243650005eed0)}, |
1473 | | {UINT64_C(0xd863b256369d4a40), UINT64_C(0x90bed43e40076a83)}, |
1474 | | {UINT64_C(0x873e4f75e2224e68), UINT64_C(0x5a7744a6e804a292)}, |
1475 | | {UINT64_C(0xa90de3535aaae202), UINT64_C(0x711515d0a205cb37)}, |
1476 | | {UINT64_C(0xd3515c2831559a83), UINT64_C(0x0d5a5b44ca873e04)}, |
1477 | | {UINT64_C(0x8412d9991ed58091), UINT64_C(0xe858790afe9486c3)}, |
1478 | | {UINT64_C(0xa5178fff668ae0b6), UINT64_C(0x626e974dbe39a873)}, |
1479 | | {UINT64_C(0xce5d73ff402d98e3), UINT64_C(0xfb0a3d212dc81290)}, |
1480 | | {UINT64_C(0x80fa687f881c7f8e), UINT64_C(0x7ce66634bc9d0b9a)}, |
1481 | | {UINT64_C(0xa139029f6a239f72), UINT64_C(0x1c1fffc1ebc44e81)}, |
1482 | | {UINT64_C(0xc987434744ac874e), UINT64_C(0xa327ffb266b56221)}, |
1483 | | {UINT64_C(0xfbe9141915d7a922), UINT64_C(0x4bf1ff9f0062baa9)}, |
1484 | | {UINT64_C(0x9d71ac8fada6c9b5), UINT64_C(0x6f773fc3603db4aa)}, |
1485 | | {UINT64_C(0xc4ce17b399107c22), UINT64_C(0xcb550fb4384d21d4)}, |
1486 | | {UINT64_C(0xf6019da07f549b2b), UINT64_C(0x7e2a53a146606a49)}, |
1487 | | {UINT64_C(0x99c102844f94e0fb), UINT64_C(0x2eda7444cbfc426e)}, |
1488 | | {UINT64_C(0xc0314325637a1939), UINT64_C(0xfa911155fefb5309)}, |
1489 | | {UINT64_C(0xf03d93eebc589f88), UINT64_C(0x793555ab7eba27cb)}, |
1490 | | {UINT64_C(0x96267c7535b763b5), UINT64_C(0x4bc1558b2f3458df)}, |
1491 | | {UINT64_C(0xbbb01b9283253ca2), UINT64_C(0x9eb1aaedfb016f17)}, |
1492 | | {UINT64_C(0xea9c227723ee8bcb), UINT64_C(0x465e15a979c1cadd)}, |
1493 | | {UINT64_C(0x92a1958a7675175f), UINT64_C(0x0bfacd89ec191eca)}, |
1494 | | {UINT64_C(0xb749faed14125d36), UINT64_C(0xcef980ec671f667c)}, |
1495 | | {UINT64_C(0xe51c79a85916f484), UINT64_C(0x82b7e12780e7401b)}, |
1496 | | {UINT64_C(0x8f31cc0937ae58d2), UINT64_C(0xd1b2ecb8b0908811)}, |
1497 | | {UINT64_C(0xb2fe3f0b8599ef07), UINT64_C(0x861fa7e6dcb4aa16)}, |
1498 | | {UINT64_C(0xdfbdcece67006ac9), UINT64_C(0x67a791e093e1d49b)}, |
1499 | | {UINT64_C(0x8bd6a141006042bd), UINT64_C(0xe0c8bb2c5c6d24e1)}, |
1500 | | {UINT64_C(0xaecc49914078536d), UINT64_C(0x58fae9f773886e19)}, |
1501 | | {UINT64_C(0xda7f5bf590966848), UINT64_C(0xaf39a475506a899f)}, |
1502 | | {UINT64_C(0x888f99797a5e012d), UINT64_C(0x6d8406c952429604)}, |
1503 | | {UINT64_C(0xaab37fd7d8f58178), UINT64_C(0xc8e5087ba6d33b84)}, |
1504 | | {UINT64_C(0xd5605fcdcf32e1d6), UINT64_C(0xfb1e4a9a90880a65)}, |
1505 | | {UINT64_C(0x855c3be0a17fcd26), UINT64_C(0x5cf2eea09a550680)}, |
1506 | | {UINT64_C(0xa6b34ad8c9dfc06f), UINT64_C(0xf42faa48c0ea481f)}, |
1507 | | {UINT64_C(0xd0601d8efc57b08b), UINT64_C(0xf13b94daf124da27)}, |
1508 | | {UINT64_C(0x823c12795db6ce57), UINT64_C(0x76c53d08d6b70859)}, |
1509 | | {UINT64_C(0xa2cb1717b52481ed), UINT64_C(0x54768c4b0c64ca6f)}, |
1510 | | {UINT64_C(0xcb7ddcdda26da268), UINT64_C(0xa9942f5dcf7dfd0a)}, |
1511 | | {UINT64_C(0xfe5d54150b090b02), UINT64_C(0xd3f93b35435d7c4d)}, |
1512 | | {UINT64_C(0x9efa548d26e5a6e1), UINT64_C(0xc47bc5014a1a6db0)}, |
1513 | | {UINT64_C(0xc6b8e9b0709f109a), UINT64_C(0x359ab6419ca1091c)}, |
1514 | | {UINT64_C(0xf867241c8cc6d4c0), UINT64_C(0xc30163d203c94b63)}, |
1515 | | {UINT64_C(0x9b407691d7fc44f8), UINT64_C(0x79e0de63425dcf1e)}, |
1516 | | {UINT64_C(0xc21094364dfb5636), UINT64_C(0x985915fc12f542e5)}, |
1517 | | {UINT64_C(0xf294b943e17a2bc4), UINT64_C(0x3e6f5b7b17b2939e)}, |
1518 | | {UINT64_C(0x979cf3ca6cec5b5a), UINT64_C(0xa705992ceecf9c43)}, |
1519 | | {UINT64_C(0xbd8430bd08277231), UINT64_C(0x50c6ff782a838354)}, |
1520 | | {UINT64_C(0xece53cec4a314ebd), UINT64_C(0xa4f8bf5635246429)}, |
1521 | | {UINT64_C(0x940f4613ae5ed136), UINT64_C(0x871b7795e136be9a)}, |
1522 | | {UINT64_C(0xb913179899f68584), UINT64_C(0x28e2557b59846e40)}, |
1523 | | {UINT64_C(0xe757dd7ec07426e5), UINT64_C(0x331aeada2fe589d0)}, |
1524 | | {UINT64_C(0x9096ea6f3848984f), UINT64_C(0x3ff0d2c85def7622)}, |
1525 | | {UINT64_C(0xb4bca50b065abe63), UINT64_C(0x0fed077a756b53aa)}, |
1526 | | {UINT64_C(0xe1ebce4dc7f16dfb), UINT64_C(0xd3e8495912c62895)}, |
1527 | | {UINT64_C(0x8d3360f09cf6e4bd), UINT64_C(0x64712dd7abbbd95d)}, |
1528 | | {UINT64_C(0xb080392cc4349dec), UINT64_C(0xbd8d794d96aacfb4)}, |
1529 | | {UINT64_C(0xdca04777f541c567), UINT64_C(0xecf0d7a0fc5583a1)}, |
1530 | | {UINT64_C(0x89e42caaf9491b60), UINT64_C(0xf41686c49db57245)}, |
1531 | | {UINT64_C(0xac5d37d5b79b6239), UINT64_C(0x311c2875c522ced6)}, |
1532 | | {UINT64_C(0xd77485cb25823ac7), UINT64_C(0x7d633293366b828c)}, |
1533 | | {UINT64_C(0x86a8d39ef77164bc), UINT64_C(0xae5dff9c02033198)}, |
1534 | | {UINT64_C(0xa8530886b54dbdeb), UINT64_C(0xd9f57f830283fdfd)}, |
1535 | | {UINT64_C(0xd267caa862a12d66), UINT64_C(0xd072df63c324fd7c)}, |
1536 | | {UINT64_C(0x8380dea93da4bc60), UINT64_C(0x4247cb9e59f71e6e)}, |
1537 | | {UINT64_C(0xa46116538d0deb78), UINT64_C(0x52d9be85f074e609)}, |
1538 | | {UINT64_C(0xcd795be870516656), UINT64_C(0x67902e276c921f8c)}, |
1539 | | {UINT64_C(0x806bd9714632dff6), UINT64_C(0x00ba1cd8a3db53b7)}, |
1540 | | {UINT64_C(0xa086cfcd97bf97f3), UINT64_C(0x80e8a40eccd228a5)}, |
1541 | | {UINT64_C(0xc8a883c0fdaf7df0), UINT64_C(0x6122cd128006b2ce)}, |
1542 | | {UINT64_C(0xfad2a4b13d1b5d6c), UINT64_C(0x796b805720085f82)}, |
1543 | | {UINT64_C(0x9cc3a6eec6311a63), UINT64_C(0xcbe3303674053bb1)}, |
1544 | | {UINT64_C(0xc3f490aa77bd60fc), UINT64_C(0xbedbfc4411068a9d)}, |
1545 | | {UINT64_C(0xf4f1b4d515acb93b), UINT64_C(0xee92fb5515482d45)}, |
1546 | | {UINT64_C(0x991711052d8bf3c5), UINT64_C(0x751bdd152d4d1c4b)}, |
1547 | | {UINT64_C(0xbf5cd54678eef0b6), UINT64_C(0xd262d45a78a0635e)}, |
1548 | | {UINT64_C(0xef340a98172aace4), UINT64_C(0x86fb897116c87c35)}, |
1549 | | {UINT64_C(0x9580869f0e7aac0e), UINT64_C(0xd45d35e6ae3d4da1)}, |
1550 | | {UINT64_C(0xbae0a846d2195712), UINT64_C(0x8974836059cca10a)}, |
1551 | | {UINT64_C(0xe998d258869facd7), UINT64_C(0x2bd1a438703fc94c)}, |
1552 | | {UINT64_C(0x91ff83775423cc06), UINT64_C(0x7b6306a34627ddd0)}, |
1553 | | {UINT64_C(0xb67f6455292cbf08), UINT64_C(0x1a3bc84c17b1d543)}, |
1554 | | {UINT64_C(0xe41f3d6a7377eeca), UINT64_C(0x20caba5f1d9e4a94)}, |
1555 | | {UINT64_C(0x8e938662882af53e), UINT64_C(0x547eb47b7282ee9d)}, |
1556 | | {UINT64_C(0xb23867fb2a35b28d), UINT64_C(0xe99e619a4f23aa44)}, |
1557 | | {UINT64_C(0xdec681f9f4c31f31), UINT64_C(0x6405fa00e2ec94d5)}, |
1558 | | {UINT64_C(0x8b3c113c38f9f37e), UINT64_C(0xde83bc408dd3dd05)}, |
1559 | | {UINT64_C(0xae0b158b4738705e), UINT64_C(0x9624ab50b148d446)}, |
1560 | | {UINT64_C(0xd98ddaee19068c76), UINT64_C(0x3badd624dd9b0958)}, |
1561 | | {UINT64_C(0x87f8a8d4cfa417c9), UINT64_C(0xe54ca5d70a80e5d7)}, |
1562 | | {UINT64_C(0xa9f6d30a038d1dbc), UINT64_C(0x5e9fcf4ccd211f4d)}, |
1563 | | {UINT64_C(0xd47487cc8470652b), UINT64_C(0x7647c32000696720)}, |
1564 | | {UINT64_C(0x84c8d4dfd2c63f3b), UINT64_C(0x29ecd9f40041e074)}, |
1565 | | {UINT64_C(0xa5fb0a17c777cf09), UINT64_C(0xf468107100525891)}, |
1566 | | {UINT64_C(0xcf79cc9db955c2cc), UINT64_C(0x7182148d4066eeb5)}, |
1567 | | {UINT64_C(0x81ac1fe293d599bf), UINT64_C(0xc6f14cd848405531)}, |
1568 | | {UINT64_C(0xa21727db38cb002f), UINT64_C(0xb8ada00e5a506a7d)}, |
1569 | | {UINT64_C(0xca9cf1d206fdc03b), UINT64_C(0xa6d90811f0e4851d)}, |
1570 | | {UINT64_C(0xfd442e4688bd304a), UINT64_C(0x908f4a166d1da664)}, |
1571 | | {UINT64_C(0x9e4a9cec15763e2e), UINT64_C(0x9a598e4e043287ff)}, |
1572 | | {UINT64_C(0xc5dd44271ad3cdba), UINT64_C(0x40eff1e1853f29fe)}, |
1573 | | {UINT64_C(0xf7549530e188c128), UINT64_C(0xd12bee59e68ef47d)}, |
1574 | | {UINT64_C(0x9a94dd3e8cf578b9), UINT64_C(0x82bb74f8301958cf)}, |
1575 | | {UINT64_C(0xc13a148e3032d6e7), UINT64_C(0xe36a52363c1faf02)}, |
1576 | | {UINT64_C(0xf18899b1bc3f8ca1), UINT64_C(0xdc44e6c3cb279ac2)}, |
1577 | | {UINT64_C(0x96f5600f15a7b7e5), UINT64_C(0x29ab103a5ef8c0ba)}, |
1578 | | {UINT64_C(0xbcb2b812db11a5de), UINT64_C(0x7415d448f6b6f0e8)}, |
1579 | | {UINT64_C(0xebdf661791d60f56), UINT64_C(0x111b495b3464ad22)}, |
1580 | | {UINT64_C(0x936b9fcebb25c995), UINT64_C(0xcab10dd900beec35)}, |
1581 | | {UINT64_C(0xb84687c269ef3bfb), UINT64_C(0x3d5d514f40eea743)}, |
1582 | | {UINT64_C(0xe65829b3046b0afa), UINT64_C(0x0cb4a5a3112a5113)}, |
1583 | | {UINT64_C(0x8ff71a0fe2c2e6dc), UINT64_C(0x47f0e785eaba72ac)}, |
1584 | | {UINT64_C(0xb3f4e093db73a093), UINT64_C(0x59ed216765690f57)}, |
1585 | | {UINT64_C(0xe0f218b8d25088b8), UINT64_C(0x306869c13ec3532d)}, |
1586 | | {UINT64_C(0x8c974f7383725573), UINT64_C(0x1e414218c73a13fc)}, |
1587 | | {UINT64_C(0xafbd2350644eeacf), UINT64_C(0xe5d1929ef90898fb)}, |
1588 | | {UINT64_C(0xdbac6c247d62a583), UINT64_C(0xdf45f746b74abf3a)}, |
1589 | | {UINT64_C(0x894bc396ce5da772), UINT64_C(0x6b8bba8c328eb784)}, |
1590 | | {UINT64_C(0xab9eb47c81f5114f), UINT64_C(0x066ea92f3f326565)}, |
1591 | | {UINT64_C(0xd686619ba27255a2), UINT64_C(0xc80a537b0efefebe)}, |
1592 | | {UINT64_C(0x8613fd0145877585), UINT64_C(0xbd06742ce95f5f37)}, |
1593 | | {UINT64_C(0xa798fc4196e952e7), UINT64_C(0x2c48113823b73705)}, |
1594 | | {UINT64_C(0xd17f3b51fca3a7a0), UINT64_C(0xf75a15862ca504c6)}, |
1595 | | {UINT64_C(0x82ef85133de648c4), UINT64_C(0x9a984d73dbe722fc)}, |
1596 | | {UINT64_C(0xa3ab66580d5fdaf5), UINT64_C(0xc13e60d0d2e0ebbb)}, |
1597 | | {UINT64_C(0xcc963fee10b7d1b3), UINT64_C(0x318df905079926a9)}, |
1598 | | {UINT64_C(0xffbbcfe994e5c61f), UINT64_C(0xfdf17746497f7053)}, |
1599 | | {UINT64_C(0x9fd561f1fd0f9bd3), UINT64_C(0xfeb6ea8bedefa634)}, |
1600 | | {UINT64_C(0xc7caba6e7c5382c8), UINT64_C(0xfe64a52ee96b8fc1)}, |
1601 | | {UINT64_C(0xf9bd690a1b68637b), UINT64_C(0x3dfdce7aa3c673b1)}, |
1602 | | {UINT64_C(0x9c1661a651213e2d), UINT64_C(0x06bea10ca65c084f)}, |
1603 | | {UINT64_C(0xc31bfa0fe5698db8), UINT64_C(0x486e494fcff30a63)}, |
1604 | | {UINT64_C(0xf3e2f893dec3f126), UINT64_C(0x5a89dba3c3efccfb)}, |
1605 | | {UINT64_C(0x986ddb5c6b3a76b7), UINT64_C(0xf89629465a75e01d)}, |
1606 | | {UINT64_C(0xbe89523386091465), UINT64_C(0xf6bbb397f1135824)}, |
1607 | | {UINT64_C(0xee2ba6c0678b597f), UINT64_C(0x746aa07ded582e2d)}, |
1608 | | {UINT64_C(0x94db483840b717ef), UINT64_C(0xa8c2a44eb4571cdd)}, |
1609 | | {UINT64_C(0xba121a4650e4ddeb), UINT64_C(0x92f34d62616ce414)}, |
1610 | | {UINT64_C(0xe896a0d7e51e1566), UINT64_C(0x77b020baf9c81d18)}, |
1611 | | {UINT64_C(0x915e2486ef32cd60), UINT64_C(0x0ace1474dc1d122f)}, |
1612 | | {UINT64_C(0xb5b5ada8aaff80b8), UINT64_C(0x0d819992132456bb)}, |
1613 | | {UINT64_C(0xe3231912d5bf60e6), UINT64_C(0x10e1fff697ed6c6a)}, |
1614 | | {UINT64_C(0x8df5efabc5979c8f), UINT64_C(0xca8d3ffa1ef463c2)}, |
1615 | | {UINT64_C(0xb1736b96b6fd83b3), UINT64_C(0xbd308ff8a6b17cb3)}, |
1616 | | {UINT64_C(0xddd0467c64bce4a0), UINT64_C(0xac7cb3f6d05ddbdf)}, |
1617 | | {UINT64_C(0x8aa22c0dbef60ee4), UINT64_C(0x6bcdf07a423aa96c)}, |
1618 | | {UINT64_C(0xad4ab7112eb3929d), UINT64_C(0x86c16c98d2c953c7)}, |
1619 | | {UINT64_C(0xd89d64d57a607744), UINT64_C(0xe871c7bf077ba8b8)}, |
1620 | | {UINT64_C(0x87625f056c7c4a8b), UINT64_C(0x11471cd764ad4973)}, |
1621 | | {UINT64_C(0xa93af6c6c79b5d2d), UINT64_C(0xd598e40d3dd89bd0)}, |
1622 | | {UINT64_C(0xd389b47879823479), UINT64_C(0x4aff1d108d4ec2c4)}, |
1623 | | {UINT64_C(0x843610cb4bf160cb), UINT64_C(0xcedf722a585139bb)}, |
1624 | | {UINT64_C(0xa54394fe1eedb8fe), UINT64_C(0xc2974eb4ee658829)}, |
1625 | | {UINT64_C(0xce947a3da6a9273e), UINT64_C(0x733d226229feea33)}, |
1626 | | {UINT64_C(0x811ccc668829b887), UINT64_C(0x0806357d5a3f5260)}, |
1627 | | {UINT64_C(0xa163ff802a3426a8), UINT64_C(0xca07c2dcb0cf26f8)}, |
1628 | | {UINT64_C(0xc9bcff6034c13052), UINT64_C(0xfc89b393dd02f0b6)}, |
1629 | | {UINT64_C(0xfc2c3f3841f17c67), UINT64_C(0xbbac2078d443ace3)}, |
1630 | | {UINT64_C(0x9d9ba7832936edc0), UINT64_C(0xd54b944b84aa4c0e)}, |
1631 | | {UINT64_C(0xc5029163f384a931), UINT64_C(0x0a9e795e65d4df12)}, |
1632 | | {UINT64_C(0xf64335bcf065d37d), UINT64_C(0x4d4617b5ff4a16d6)}, |
1633 | | {UINT64_C(0x99ea0196163fa42e), UINT64_C(0x504bced1bf8e4e46)}, |
1634 | | {UINT64_C(0xc06481fb9bcf8d39), UINT64_C(0xe45ec2862f71e1d7)}, |
1635 | | {UINT64_C(0xf07da27a82c37088), UINT64_C(0x5d767327bb4e5a4d)}, |
1636 | | {UINT64_C(0x964e858c91ba2655), UINT64_C(0x3a6a07f8d510f870)}, |
1637 | | {UINT64_C(0xbbe226efb628afea), UINT64_C(0x890489f70a55368c)}, |
1638 | | {UINT64_C(0xeadab0aba3b2dbe5), UINT64_C(0x2b45ac74ccea842f)}, |
1639 | | {UINT64_C(0x92c8ae6b464fc96f), UINT64_C(0x3b0b8bc90012929e)}, |
1640 | | {UINT64_C(0xb77ada0617e3bbcb), UINT64_C(0x09ce6ebb40173745)}, |
1641 | | {UINT64_C(0xe55990879ddcaabd), UINT64_C(0xcc420a6a101d0516)}, |
1642 | | {UINT64_C(0x8f57fa54c2a9eab6), UINT64_C(0x9fa946824a12232e)}, |
1643 | | {UINT64_C(0xb32df8e9f3546564), UINT64_C(0x47939822dc96abfa)}, |
1644 | | {UINT64_C(0xdff9772470297ebd), UINT64_C(0x59787e2b93bc56f8)}, |
1645 | | {UINT64_C(0x8bfbea76c619ef36), UINT64_C(0x57eb4edb3c55b65b)}, |
1646 | | {UINT64_C(0xaefae51477a06b03), UINT64_C(0xede622920b6b23f2)}, |
1647 | | {UINT64_C(0xdab99e59958885c4), UINT64_C(0xe95fab368e45ecee)}, |
1648 | | {UINT64_C(0x88b402f7fd75539b), UINT64_C(0x11dbcb0218ebb415)}, |
1649 | | {UINT64_C(0xaae103b5fcd2a881), UINT64_C(0xd652bdc29f26a11a)}, |
1650 | | {UINT64_C(0xd59944a37c0752a2), UINT64_C(0x4be76d3346f04960)}, |
1651 | | {UINT64_C(0x857fcae62d8493a5), UINT64_C(0x6f70a4400c562ddc)}, |
1652 | | {UINT64_C(0xa6dfbd9fb8e5b88e), UINT64_C(0xcb4ccd500f6bb953)}, |
1653 | | {UINT64_C(0xd097ad07a71f26b2), UINT64_C(0x7e2000a41346a7a8)}, |
1654 | | {UINT64_C(0x825ecc24c873782f), UINT64_C(0x8ed400668c0c28c9)}, |
1655 | | {UINT64_C(0xa2f67f2dfa90563b), UINT64_C(0x728900802f0f32fb)}, |
1656 | | {UINT64_C(0xcbb41ef979346bca), UINT64_C(0x4f2b40a03ad2ffba)}, |
1657 | | {UINT64_C(0xfea126b7d78186bc), UINT64_C(0xe2f610c84987bfa9)}, |
1658 | | {UINT64_C(0x9f24b832e6b0f436), UINT64_C(0x0dd9ca7d2df4d7ca)}, |
1659 | | {UINT64_C(0xc6ede63fa05d3143), UINT64_C(0x91503d1c79720dbc)}, |
1660 | | {UINT64_C(0xf8a95fcf88747d94), UINT64_C(0x75a44c6397ce912b)}, |
1661 | | {UINT64_C(0x9b69dbe1b548ce7c), UINT64_C(0xc986afbe3ee11abb)}, |
1662 | | {UINT64_C(0xc24452da229b021b), UINT64_C(0xfbe85badce996169)}, |
1663 | | {UINT64_C(0xf2d56790ab41c2a2), UINT64_C(0xfae27299423fb9c4)}, |
1664 | | {UINT64_C(0x97c560ba6b0919a5), UINT64_C(0xdccd879fc967d41b)}, |
1665 | | {UINT64_C(0xbdb6b8e905cb600f), UINT64_C(0x5400e987bbc1c921)}, |
1666 | | {UINT64_C(0xed246723473e3813), UINT64_C(0x290123e9aab23b69)}, |
1667 | | {UINT64_C(0x9436c0760c86e30b), UINT64_C(0xf9a0b6720aaf6522)}, |
1668 | | {UINT64_C(0xb94470938fa89bce), UINT64_C(0xf808e40e8d5b3e6a)}, |
1669 | | {UINT64_C(0xe7958cb87392c2c2), UINT64_C(0xb60b1d1230b20e05)}, |
1670 | | {UINT64_C(0x90bd77f3483bb9b9), UINT64_C(0xb1c6f22b5e6f48c3)}, |
1671 | | {UINT64_C(0xb4ecd5f01a4aa828), UINT64_C(0x1e38aeb6360b1af4)}, |
1672 | | {UINT64_C(0xe2280b6c20dd5232), UINT64_C(0x25c6da63c38de1b1)}, |
1673 | | {UINT64_C(0x8d590723948a535f), UINT64_C(0x579c487e5a38ad0f)}, |
1674 | | {UINT64_C(0xb0af48ec79ace837), UINT64_C(0x2d835a9df0c6d852)}, |
1675 | | {UINT64_C(0xdcdb1b2798182244), UINT64_C(0xf8e431456cf88e66)}, |
1676 | | {UINT64_C(0x8a08f0f8bf0f156b), UINT64_C(0x1b8e9ecb641b5900)}, |
1677 | | {UINT64_C(0xac8b2d36eed2dac5), UINT64_C(0xe272467e3d222f40)}, |
1678 | | {UINT64_C(0xd7adf884aa879177), UINT64_C(0x5b0ed81dcc6abb10)}, |
1679 | | {UINT64_C(0x86ccbb52ea94baea), UINT64_C(0x98e947129fc2b4ea)}, |
1680 | | {UINT64_C(0xa87fea27a539e9a5), UINT64_C(0x3f2398d747b36225)}, |
1681 | | {UINT64_C(0xd29fe4b18e88640e), UINT64_C(0x8eec7f0d19a03aae)}, |
1682 | | {UINT64_C(0x83a3eeeef9153e89), UINT64_C(0x1953cf68300424ad)}, |
1683 | | {UINT64_C(0xa48ceaaab75a8e2b), UINT64_C(0x5fa8c3423c052dd8)}, |
1684 | | {UINT64_C(0xcdb02555653131b6), UINT64_C(0x3792f412cb06794e)}, |
1685 | | {UINT64_C(0x808e17555f3ebf11), UINT64_C(0xe2bbd88bbee40bd1)}, |
1686 | | {UINT64_C(0xa0b19d2ab70e6ed6), UINT64_C(0x5b6aceaeae9d0ec5)}, |
1687 | | {UINT64_C(0xc8de047564d20a8b), UINT64_C(0xf245825a5a445276)}, |
1688 | | {UINT64_C(0xfb158592be068d2e), UINT64_C(0xeed6e2f0f0d56713)}, |
1689 | | {UINT64_C(0x9ced737bb6c4183d), UINT64_C(0x55464dd69685606c)}, |
1690 | | {UINT64_C(0xc428d05aa4751e4c), UINT64_C(0xaa97e14c3c26b887)}, |
1691 | | {UINT64_C(0xf53304714d9265df), UINT64_C(0xd53dd99f4b3066a9)}, |
1692 | | {UINT64_C(0x993fe2c6d07b7fab), UINT64_C(0xe546a8038efe402a)}, |
1693 | | {UINT64_C(0xbf8fdb78849a5f96), UINT64_C(0xde98520472bdd034)}, |
1694 | | {UINT64_C(0xef73d256a5c0f77c), UINT64_C(0x963e66858f6d4441)}, |
1695 | | {UINT64_C(0x95a8637627989aad), UINT64_C(0xdde7001379a44aa9)}, |
1696 | | {UINT64_C(0xbb127c53b17ec159), UINT64_C(0x5560c018580d5d53)}, |
1697 | | {UINT64_C(0xe9d71b689dde71af), UINT64_C(0xaab8f01e6e10b4a7)}, |
1698 | | {UINT64_C(0x9226712162ab070d), UINT64_C(0xcab3961304ca70e9)}, |
1699 | | {UINT64_C(0xb6b00d69bb55c8d1), UINT64_C(0x3d607b97c5fd0d23)}, |
1700 | | {UINT64_C(0xe45c10c42a2b3b05), UINT64_C(0x8cb89a7db77c506b)}, |
1701 | | {UINT64_C(0x8eb98a7a9a5b04e3), UINT64_C(0x77f3608e92adb243)}, |
1702 | | {UINT64_C(0xb267ed1940f1c61c), UINT64_C(0x55f038b237591ed4)}, |
1703 | | {UINT64_C(0xdf01e85f912e37a3), UINT64_C(0x6b6c46dec52f6689)}, |
1704 | | {UINT64_C(0x8b61313bbabce2c6), UINT64_C(0x2323ac4b3b3da016)}, |
1705 | | {UINT64_C(0xae397d8aa96c1b77), UINT64_C(0xabec975e0a0d081b)}, |
1706 | | {UINT64_C(0xd9c7dced53c72255), UINT64_C(0x96e7bd358c904a22)}, |
1707 | | {UINT64_C(0x881cea14545c7575), UINT64_C(0x7e50d64177da2e55)}, |
1708 | | {UINT64_C(0xaa242499697392d2), UINT64_C(0xdde50bd1d5d0b9ea)}, |
1709 | | {UINT64_C(0xd4ad2dbfc3d07787), UINT64_C(0x955e4ec64b44e865)}, |
1710 | | {UINT64_C(0x84ec3c97da624ab4), UINT64_C(0xbd5af13bef0b113f)}, |
1711 | | {UINT64_C(0xa6274bbdd0fadd61), UINT64_C(0xecb1ad8aeacdd58f)}, |
1712 | | {UINT64_C(0xcfb11ead453994ba), UINT64_C(0x67de18eda5814af3)}, |
1713 | | {UINT64_C(0x81ceb32c4b43fcf4), UINT64_C(0x80eacf948770ced8)}, |
1714 | | {UINT64_C(0xa2425ff75e14fc31), UINT64_C(0xa1258379a94d028e)}, |
1715 | | {UINT64_C(0xcad2f7f5359a3b3e), UINT64_C(0x096ee45813a04331)}, |
1716 | | {UINT64_C(0xfd87b5f28300ca0d), UINT64_C(0x8bca9d6e188853fd)}, |
1717 | | {UINT64_C(0x9e74d1b791e07e48), UINT64_C(0x775ea264cf55347e)}, |
1718 | | {UINT64_C(0xc612062576589dda), UINT64_C(0x95364afe032a819e)}, |
1719 | | {UINT64_C(0xf79687aed3eec551), UINT64_C(0x3a83ddbd83f52205)}, |
1720 | | {UINT64_C(0x9abe14cd44753b52), UINT64_C(0xc4926a9672793543)}, |
1721 | | {UINT64_C(0xc16d9a0095928a27), UINT64_C(0x75b7053c0f178294)}, |
1722 | | {UINT64_C(0xf1c90080baf72cb1), UINT64_C(0x5324c68b12dd6339)}, |
1723 | | {UINT64_C(0x971da05074da7bee), UINT64_C(0xd3f6fc16ebca5e04)}, |
1724 | | {UINT64_C(0xbce5086492111aea), UINT64_C(0x88f4bb1ca6bcf585)}, |
1725 | | {UINT64_C(0xec1e4a7db69561a5), UINT64_C(0x2b31e9e3d06c32e6)}, |
1726 | | {UINT64_C(0x9392ee8e921d5d07), UINT64_C(0x3aff322e62439fd0)}, |
1727 | | {UINT64_C(0xb877aa3236a4b449), UINT64_C(0x09befeb9fad487c3)}, |
1728 | | {UINT64_C(0xe69594bec44de15b), UINT64_C(0x4c2ebe687989a9b4)}, |
1729 | | {UINT64_C(0x901d7cf73ab0acd9), UINT64_C(0x0f9d37014bf60a11)}, |
1730 | | {UINT64_C(0xb424dc35095cd80f), UINT64_C(0x538484c19ef38c95)}, |
1731 | | {UINT64_C(0xe12e13424bb40e13), UINT64_C(0x2865a5f206b06fba)}, |
1732 | | {UINT64_C(0x8cbccc096f5088cb), UINT64_C(0xf93f87b7442e45d4)}, |
1733 | | {UINT64_C(0xafebff0bcb24aafe), UINT64_C(0xf78f69a51539d749)}, |
1734 | | {UINT64_C(0xdbe6fecebdedd5be), UINT64_C(0xb573440e5a884d1c)}, |
1735 | | {UINT64_C(0x89705f4136b4a597), UINT64_C(0x31680a88f8953031)}, |
1736 | | {UINT64_C(0xabcc77118461cefc), UINT64_C(0xfdc20d2b36ba7c3e)}, |
1737 | | {UINT64_C(0xd6bf94d5e57a42bc), UINT64_C(0x3d32907604691b4d)}, |
1738 | | {UINT64_C(0x8637bd05af6c69b5), UINT64_C(0xa63f9a49c2c1b110)}, |
1739 | | {UINT64_C(0xa7c5ac471b478423), UINT64_C(0x0fcf80dc33721d54)}, |
1740 | | {UINT64_C(0xd1b71758e219652b), UINT64_C(0xd3c36113404ea4a9)}, |
1741 | | {UINT64_C(0x83126e978d4fdf3b), UINT64_C(0x645a1cac083126ea)}, |
1742 | | {UINT64_C(0xa3d70a3d70a3d70a), UINT64_C(0x3d70a3d70a3d70a4)}, |
1743 | | {UINT64_C(0xcccccccccccccccc), UINT64_C(0xcccccccccccccccd)}, |
1744 | | {UINT64_C(0x8000000000000000), UINT64_C(0x0000000000000000)}, |
1745 | | {UINT64_C(0xa000000000000000), UINT64_C(0x0000000000000000)}, |
1746 | | {UINT64_C(0xc800000000000000), UINT64_C(0x0000000000000000)}, |
1747 | | {UINT64_C(0xfa00000000000000), UINT64_C(0x0000000000000000)}, |
1748 | | {UINT64_C(0x9c40000000000000), UINT64_C(0x0000000000000000)}, |
1749 | | {UINT64_C(0xc350000000000000), UINT64_C(0x0000000000000000)}, |
1750 | | {UINT64_C(0xf424000000000000), UINT64_C(0x0000000000000000)}, |
1751 | | {UINT64_C(0x9896800000000000), UINT64_C(0x0000000000000000)}, |
1752 | | {UINT64_C(0xbebc200000000000), UINT64_C(0x0000000000000000)}, |
1753 | | {UINT64_C(0xee6b280000000000), UINT64_C(0x0000000000000000)}, |
1754 | | {UINT64_C(0x9502f90000000000), UINT64_C(0x0000000000000000)}, |
1755 | | {UINT64_C(0xba43b74000000000), UINT64_C(0x0000000000000000)}, |
1756 | | {UINT64_C(0xe8d4a51000000000), UINT64_C(0x0000000000000000)}, |
1757 | | {UINT64_C(0x9184e72a00000000), UINT64_C(0x0000000000000000)}, |
1758 | | {UINT64_C(0xb5e620f480000000), UINT64_C(0x0000000000000000)}, |
1759 | | {UINT64_C(0xe35fa931a0000000), UINT64_C(0x0000000000000000)}, |
1760 | | {UINT64_C(0x8e1bc9bf04000000), UINT64_C(0x0000000000000000)}, |
1761 | | {UINT64_C(0xb1a2bc2ec5000000), UINT64_C(0x0000000000000000)}, |
1762 | | {UINT64_C(0xde0b6b3a76400000), UINT64_C(0x0000000000000000)}, |
1763 | | {UINT64_C(0x8ac7230489e80000), UINT64_C(0x0000000000000000)}, |
1764 | | {UINT64_C(0xad78ebc5ac620000), UINT64_C(0x0000000000000000)}, |
1765 | | {UINT64_C(0xd8d726b7177a8000), UINT64_C(0x0000000000000000)}, |
1766 | | {UINT64_C(0x878678326eac9000), UINT64_C(0x0000000000000000)}, |
1767 | | {UINT64_C(0xa968163f0a57b400), UINT64_C(0x0000000000000000)}, |
1768 | | {UINT64_C(0xd3c21bcecceda100), UINT64_C(0x0000000000000000)}, |
1769 | | {UINT64_C(0x84595161401484a0), UINT64_C(0x0000000000000000)}, |
1770 | | {UINT64_C(0xa56fa5b99019a5c8), UINT64_C(0x0000000000000000)}, |
1771 | | {UINT64_C(0xcecb8f27f4200f3a), UINT64_C(0x0000000000000000)}, |
1772 | | {UINT64_C(0x813f3978f8940984), UINT64_C(0x4000000000000000)}, |
1773 | | {UINT64_C(0xa18f07d736b90be5), UINT64_C(0x5000000000000000)}, |
1774 | | {UINT64_C(0xc9f2c9cd04674ede), UINT64_C(0xa400000000000000)}, |
1775 | | {UINT64_C(0xfc6f7c4045812296), UINT64_C(0x4d00000000000000)}, |
1776 | | {UINT64_C(0x9dc5ada82b70b59d), UINT64_C(0xf020000000000000)}, |
1777 | | {UINT64_C(0xc5371912364ce305), UINT64_C(0x6c28000000000000)}, |
1778 | | {UINT64_C(0xf684df56c3e01bc6), UINT64_C(0xc732000000000000)}, |
1779 | | {UINT64_C(0x9a130b963a6c115c), UINT64_C(0x3c7f400000000000)}, |
1780 | | {UINT64_C(0xc097ce7bc90715b3), UINT64_C(0x4b9f100000000000)}, |
1781 | | {UINT64_C(0xf0bdc21abb48db20), UINT64_C(0x1e86d40000000000)}, |
1782 | | {UINT64_C(0x96769950b50d88f4), UINT64_C(0x1314448000000000)}, |
1783 | | {UINT64_C(0xbc143fa4e250eb31), UINT64_C(0x17d955a000000000)}, |
1784 | | {UINT64_C(0xeb194f8e1ae525fd), UINT64_C(0x5dcfab0800000000)}, |
1785 | | {UINT64_C(0x92efd1b8d0cf37be), UINT64_C(0x5aa1cae500000000)}, |
1786 | | {UINT64_C(0xb7abc627050305ad), UINT64_C(0xf14a3d9e40000000)}, |
1787 | | {UINT64_C(0xe596b7b0c643c719), UINT64_C(0x6d9ccd05d0000000)}, |
1788 | | {UINT64_C(0x8f7e32ce7bea5c6f), UINT64_C(0xe4820023a2000000)}, |
1789 | | {UINT64_C(0xb35dbf821ae4f38b), UINT64_C(0xdda2802c8a800000)}, |
1790 | | {UINT64_C(0xe0352f62a19e306e), UINT64_C(0xd50b2037ad200000)}, |
1791 | | {UINT64_C(0x8c213d9da502de45), UINT64_C(0x4526f422cc340000)}, |
1792 | | {UINT64_C(0xaf298d050e4395d6), UINT64_C(0x9670b12b7f410000)}, |
1793 | | {UINT64_C(0xdaf3f04651d47b4c), UINT64_C(0x3c0cdd765f114000)}, |
1794 | | {UINT64_C(0x88d8762bf324cd0f), UINT64_C(0xa5880a69fb6ac800)}, |
1795 | | {UINT64_C(0xab0e93b6efee0053), UINT64_C(0x8eea0d047a457a00)}, |
1796 | | {UINT64_C(0xd5d238a4abe98068), UINT64_C(0x72a4904598d6d880)}, |
1797 | | {UINT64_C(0x85a36366eb71f041), UINT64_C(0x47a6da2b7f864750)}, |
1798 | | {UINT64_C(0xa70c3c40a64e6c51), UINT64_C(0x999090b65f67d924)}, |
1799 | | {UINT64_C(0xd0cf4b50cfe20765), UINT64_C(0xfff4b4e3f741cf6d)}, |
1800 | | {UINT64_C(0x82818f1281ed449f), UINT64_C(0xbff8f10e7a8921a5)}, |
1801 | | {UINT64_C(0xa321f2d7226895c7), UINT64_C(0xaff72d52192b6a0e)}, |
1802 | | {UINT64_C(0xcbea6f8ceb02bb39), UINT64_C(0x9bf4f8a69f764491)}, |
1803 | | {UINT64_C(0xfee50b7025c36a08), UINT64_C(0x02f236d04753d5b5)}, |
1804 | | {UINT64_C(0x9f4f2726179a2245), UINT64_C(0x01d762422c946591)}, |
1805 | | {UINT64_C(0xc722f0ef9d80aad6), UINT64_C(0x424d3ad2b7b97ef6)}, |
1806 | | {UINT64_C(0xf8ebad2b84e0d58b), UINT64_C(0xd2e0898765a7deb3)}, |
1807 | | {UINT64_C(0x9b934c3b330c8577), UINT64_C(0x63cc55f49f88eb30)}, |
1808 | | {UINT64_C(0xc2781f49ffcfa6d5), UINT64_C(0x3cbf6b71c76b25fc)}, |
1809 | | {UINT64_C(0xf316271c7fc3908a), UINT64_C(0x8bef464e3945ef7b)}, |
1810 | | {UINT64_C(0x97edd871cfda3a56), UINT64_C(0x97758bf0e3cbb5ad)}, |
1811 | | {UINT64_C(0xbde94e8e43d0c8ec), UINT64_C(0x3d52eeed1cbea318)}, |
1812 | | {UINT64_C(0xed63a231d4c4fb27), UINT64_C(0x4ca7aaa863ee4bde)}, |
1813 | | {UINT64_C(0x945e455f24fb1cf8), UINT64_C(0x8fe8caa93e74ef6b)}, |
1814 | | {UINT64_C(0xb975d6b6ee39e436), UINT64_C(0xb3e2fd538e122b45)}, |
1815 | | {UINT64_C(0xe7d34c64a9c85d44), UINT64_C(0x60dbbca87196b617)}, |
1816 | | {UINT64_C(0x90e40fbeea1d3a4a), UINT64_C(0xbc8955e946fe31ce)}, |
1817 | | {UINT64_C(0xb51d13aea4a488dd), UINT64_C(0x6babab6398bdbe42)}, |
1818 | | {UINT64_C(0xe264589a4dcdab14), UINT64_C(0xc696963c7eed2dd2)}, |
1819 | | {UINT64_C(0x8d7eb76070a08aec), UINT64_C(0xfc1e1de5cf543ca3)}, |
1820 | | {UINT64_C(0xb0de65388cc8ada8), UINT64_C(0x3b25a55f43294bcc)}, |
1821 | | {UINT64_C(0xdd15fe86affad912), UINT64_C(0x49ef0eb713f39ebf)}, |
1822 | | {UINT64_C(0x8a2dbf142dfcc7ab), UINT64_C(0x6e3569326c784338)}, |
1823 | | {UINT64_C(0xacb92ed9397bf996), UINT64_C(0x49c2c37f07965405)}, |
1824 | | {UINT64_C(0xd7e77a8f87daf7fb), UINT64_C(0xdc33745ec97be907)}, |
1825 | | {UINT64_C(0x86f0ac99b4e8dafd), UINT64_C(0x69a028bb3ded71a4)}, |
1826 | | {UINT64_C(0xa8acd7c0222311bc), UINT64_C(0xc40832ea0d68ce0d)}, |
1827 | | {UINT64_C(0xd2d80db02aabd62b), UINT64_C(0xf50a3fa490c30191)}, |
1828 | | {UINT64_C(0x83c7088e1aab65db), UINT64_C(0x792667c6da79e0fb)}, |
1829 | | {UINT64_C(0xa4b8cab1a1563f52), UINT64_C(0x577001b891185939)}, |
1830 | | {UINT64_C(0xcde6fd5e09abcf26), UINT64_C(0xed4c0226b55e6f87)}, |
1831 | | {UINT64_C(0x80b05e5ac60b6178), UINT64_C(0x544f8158315b05b5)}, |
1832 | | {UINT64_C(0xa0dc75f1778e39d6), UINT64_C(0x696361ae3db1c722)}, |
1833 | | {UINT64_C(0xc913936dd571c84c), UINT64_C(0x03bc3a19cd1e38ea)}, |
1834 | | {UINT64_C(0xfb5878494ace3a5f), UINT64_C(0x04ab48a04065c724)}, |
1835 | | {UINT64_C(0x9d174b2dcec0e47b), UINT64_C(0x62eb0d64283f9c77)}, |
1836 | | {UINT64_C(0xc45d1df942711d9a), UINT64_C(0x3ba5d0bd324f8395)}, |
1837 | | {UINT64_C(0xf5746577930d6500), UINT64_C(0xca8f44ec7ee3647a)}, |
1838 | | {UINT64_C(0x9968bf6abbe85f20), UINT64_C(0x7e998b13cf4e1ecc)}, |
1839 | | {UINT64_C(0xbfc2ef456ae276e8), UINT64_C(0x9e3fedd8c321a67f)}, |
1840 | | {UINT64_C(0xefb3ab16c59b14a2), UINT64_C(0xc5cfe94ef3ea101f)}, |
1841 | | {UINT64_C(0x95d04aee3b80ece5), UINT64_C(0xbba1f1d158724a13)}, |
1842 | | {UINT64_C(0xbb445da9ca61281f), UINT64_C(0x2a8a6e45ae8edc98)}, |
1843 | | {UINT64_C(0xea1575143cf97226), UINT64_C(0xf52d09d71a3293be)}, |
1844 | | {UINT64_C(0x924d692ca61be758), UINT64_C(0x593c2626705f9c57)}, |
1845 | | {UINT64_C(0xb6e0c377cfa2e12e), UINT64_C(0x6f8b2fb00c77836d)}, |
1846 | | {UINT64_C(0xe498f455c38b997a), UINT64_C(0x0b6dfb9c0f956448)}, |
1847 | | {UINT64_C(0x8edf98b59a373fec), UINT64_C(0x4724bd4189bd5ead)}, |
1848 | | {UINT64_C(0xb2977ee300c50fe7), UINT64_C(0x58edec91ec2cb658)}, |
1849 | | {UINT64_C(0xdf3d5e9bc0f653e1), UINT64_C(0x2f2967b66737e3ee)}, |
1850 | | {UINT64_C(0x8b865b215899f46c), UINT64_C(0xbd79e0d20082ee75)}, |
1851 | | {UINT64_C(0xae67f1e9aec07187), UINT64_C(0xecd8590680a3aa12)}, |
1852 | | {UINT64_C(0xda01ee641a708de9), UINT64_C(0xe80e6f4820cc9496)}, |
1853 | | {UINT64_C(0x884134fe908658b2), UINT64_C(0x3109058d147fdcde)}, |
1854 | | {UINT64_C(0xaa51823e34a7eede), UINT64_C(0xbd4b46f0599fd416)}, |
1855 | | {UINT64_C(0xd4e5e2cdc1d1ea96), UINT64_C(0x6c9e18ac7007c91b)}, |
1856 | | {UINT64_C(0x850fadc09923329e), UINT64_C(0x03e2cf6bc604ddb1)}, |
1857 | | {UINT64_C(0xa6539930bf6bff45), UINT64_C(0x84db8346b786151d)}, |
1858 | | {UINT64_C(0xcfe87f7cef46ff16), UINT64_C(0xe612641865679a64)}, |
1859 | | {UINT64_C(0x81f14fae158c5f6e), UINT64_C(0x4fcb7e8f3f60c07f)}, |
1860 | | {UINT64_C(0xa26da3999aef7749), UINT64_C(0xe3be5e330f38f09e)}, |
1861 | | {UINT64_C(0xcb090c8001ab551c), UINT64_C(0x5cadf5bfd3072cc6)}, |
1862 | | {UINT64_C(0xfdcb4fa002162a63), UINT64_C(0x73d9732fc7c8f7f7)}, |
1863 | | {UINT64_C(0x9e9f11c4014dda7e), UINT64_C(0x2867e7fddcdd9afb)}, |
1864 | | {UINT64_C(0xc646d63501a1511d), UINT64_C(0xb281e1fd541501b9)}, |
1865 | | {UINT64_C(0xf7d88bc24209a565), UINT64_C(0x1f225a7ca91a4227)}, |
1866 | | {UINT64_C(0x9ae757596946075f), UINT64_C(0x3375788de9b06959)}, |
1867 | | {UINT64_C(0xc1a12d2fc3978937), UINT64_C(0x0052d6b1641c83af)}, |
1868 | | {UINT64_C(0xf209787bb47d6b84), UINT64_C(0xc0678c5dbd23a49b)}, |
1869 | | {UINT64_C(0x9745eb4d50ce6332), UINT64_C(0xf840b7ba963646e1)}, |
1870 | | {UINT64_C(0xbd176620a501fbff), UINT64_C(0xb650e5a93bc3d899)}, |
1871 | | {UINT64_C(0xec5d3fa8ce427aff), UINT64_C(0xa3e51f138ab4cebf)}, |
1872 | | {UINT64_C(0x93ba47c980e98cdf), UINT64_C(0xc66f336c36b10138)}, |
1873 | | {UINT64_C(0xb8a8d9bbe123f017), UINT64_C(0xb80b0047445d4185)}, |
1874 | | {UINT64_C(0xe6d3102ad96cec1d), UINT64_C(0xa60dc059157491e6)}, |
1875 | | {UINT64_C(0x9043ea1ac7e41392), UINT64_C(0x87c89837ad68db30)}, |
1876 | | {UINT64_C(0xb454e4a179dd1877), UINT64_C(0x29babe4598c311fc)}, |
1877 | | {UINT64_C(0xe16a1dc9d8545e94), UINT64_C(0xf4296dd6fef3d67b)}, |
1878 | | {UINT64_C(0x8ce2529e2734bb1d), UINT64_C(0x1899e4a65f58660d)}, |
1879 | | {UINT64_C(0xb01ae745b101e9e4), UINT64_C(0x5ec05dcff72e7f90)}, |
1880 | | {UINT64_C(0xdc21a1171d42645d), UINT64_C(0x76707543f4fa1f74)}, |
1881 | | {UINT64_C(0x899504ae72497eba), UINT64_C(0x6a06494a791c53a9)}, |
1882 | | {UINT64_C(0xabfa45da0edbde69), UINT64_C(0x0487db9d17636893)}, |
1883 | | {UINT64_C(0xd6f8d7509292d603), UINT64_C(0x45a9d2845d3c42b7)}, |
1884 | | {UINT64_C(0x865b86925b9bc5c2), UINT64_C(0x0b8a2392ba45a9b3)}, |
1885 | | {UINT64_C(0xa7f26836f282b732), UINT64_C(0x8e6cac7768d7141f)}, |
1886 | | {UINT64_C(0xd1ef0244af2364ff), UINT64_C(0x3207d795430cd927)}, |
1887 | | {UINT64_C(0x8335616aed761f1f), UINT64_C(0x7f44e6bd49e807b9)}, |
1888 | | {UINT64_C(0xa402b9c5a8d3a6e7), UINT64_C(0x5f16206c9c6209a7)}, |
1889 | | {UINT64_C(0xcd036837130890a1), UINT64_C(0x36dba887c37a8c10)}, |
1890 | | {UINT64_C(0x802221226be55a64), UINT64_C(0xc2494954da2c978a)}, |
1891 | | {UINT64_C(0xa02aa96b06deb0fd), UINT64_C(0xf2db9baa10b7bd6d)}, |
1892 | | {UINT64_C(0xc83553c5c8965d3d), UINT64_C(0x6f92829494e5acc8)}, |
1893 | | {UINT64_C(0xfa42a8b73abbf48c), UINT64_C(0xcb772339ba1f17fa)}, |
1894 | | {UINT64_C(0x9c69a97284b578d7), UINT64_C(0xff2a760414536efc)}, |
1895 | | {UINT64_C(0xc38413cf25e2d70d), UINT64_C(0xfef5138519684abb)}, |
1896 | | {UINT64_C(0xf46518c2ef5b8cd1), UINT64_C(0x7eb258665fc25d6a)}, |
1897 | | {UINT64_C(0x98bf2f79d5993802), UINT64_C(0xef2f773ffbd97a62)}, |
1898 | | {UINT64_C(0xbeeefb584aff8603), UINT64_C(0xaafb550ffacfd8fb)}, |
1899 | | {UINT64_C(0xeeaaba2e5dbf6784), UINT64_C(0x95ba2a53f983cf39)}, |
1900 | | {UINT64_C(0x952ab45cfa97a0b2), UINT64_C(0xdd945a747bf26184)}, |
1901 | | {UINT64_C(0xba756174393d88df), UINT64_C(0x94f971119aeef9e5)}, |
1902 | | {UINT64_C(0xe912b9d1478ceb17), UINT64_C(0x7a37cd5601aab85e)}, |
1903 | | {UINT64_C(0x91abb422ccb812ee), UINT64_C(0xac62e055c10ab33b)}, |
1904 | | {UINT64_C(0xb616a12b7fe617aa), UINT64_C(0x577b986b314d600a)}, |
1905 | | {UINT64_C(0xe39c49765fdf9d94), UINT64_C(0xed5a7e85fda0b80c)}, |
1906 | | {UINT64_C(0x8e41ade9fbebc27d), UINT64_C(0x14588f13be847308)}, |
1907 | | {UINT64_C(0xb1d219647ae6b31c), UINT64_C(0x596eb2d8ae258fc9)}, |
1908 | | {UINT64_C(0xde469fbd99a05fe3), UINT64_C(0x6fca5f8ed9aef3bc)}, |
1909 | | {UINT64_C(0x8aec23d680043bee), UINT64_C(0x25de7bb9480d5855)}, |
1910 | | {UINT64_C(0xada72ccc20054ae9), UINT64_C(0xaf561aa79a10ae6b)}, |
1911 | | {UINT64_C(0xd910f7ff28069da4), UINT64_C(0x1b2ba1518094da05)}, |
1912 | | {UINT64_C(0x87aa9aff79042286), UINT64_C(0x90fb44d2f05d0843)}, |
1913 | | {UINT64_C(0xa99541bf57452b28), UINT64_C(0x353a1607ac744a54)}, |
1914 | | {UINT64_C(0xd3fa922f2d1675f2), UINT64_C(0x42889b8997915ce9)}, |
1915 | | {UINT64_C(0x847c9b5d7c2e09b7), UINT64_C(0x69956135febada12)}, |
1916 | | {UINT64_C(0xa59bc234db398c25), UINT64_C(0x43fab9837e699096)}, |
1917 | | {UINT64_C(0xcf02b2c21207ef2e), UINT64_C(0x94f967e45e03f4bc)}, |
1918 | | {UINT64_C(0x8161afb94b44f57d), UINT64_C(0x1d1be0eebac278f6)}, |
1919 | | {UINT64_C(0xa1ba1ba79e1632dc), UINT64_C(0x6462d92a69731733)}, |
1920 | | {UINT64_C(0xca28a291859bbf93), UINT64_C(0x7d7b8f7503cfdcff)}, |
1921 | | {UINT64_C(0xfcb2cb35e702af78), UINT64_C(0x5cda735244c3d43f)}, |
1922 | | {UINT64_C(0x9defbf01b061adab), UINT64_C(0x3a0888136afa64a8)}, |
1923 | | {UINT64_C(0xc56baec21c7a1916), UINT64_C(0x088aaa1845b8fdd1)}, |
1924 | | {UINT64_C(0xf6c69a72a3989f5b), UINT64_C(0x8aad549e57273d46)}, |
1925 | | {UINT64_C(0x9a3c2087a63f6399), UINT64_C(0x36ac54e2f678864c)}, |
1926 | | {UINT64_C(0xc0cb28a98fcf3c7f), UINT64_C(0x84576a1bb416a7de)}, |
1927 | | {UINT64_C(0xf0fdf2d3f3c30b9f), UINT64_C(0x656d44a2a11c51d6)}, |
1928 | | {UINT64_C(0x969eb7c47859e743), UINT64_C(0x9f644ae5a4b1b326)}, |
1929 | | {UINT64_C(0xbc4665b596706114), UINT64_C(0x873d5d9f0dde1fef)}, |
1930 | | {UINT64_C(0xeb57ff22fc0c7959), UINT64_C(0xa90cb506d155a7eb)}, |
1931 | | {UINT64_C(0x9316ff75dd87cbd8), UINT64_C(0x09a7f12442d588f3)}, |
1932 | | {UINT64_C(0xb7dcbf5354e9bece), UINT64_C(0x0c11ed6d538aeb30)}, |
1933 | | {UINT64_C(0xe5d3ef282a242e81), UINT64_C(0x8f1668c8a86da5fb)}, |
1934 | | {UINT64_C(0x8fa475791a569d10), UINT64_C(0xf96e017d694487bd)}, |
1935 | | {UINT64_C(0xb38d92d760ec4455), UINT64_C(0x37c981dcc395a9ad)}, |
1936 | | {UINT64_C(0xe070f78d3927556a), UINT64_C(0x85bbe253f47b1418)}, |
1937 | | {UINT64_C(0x8c469ab843b89562), UINT64_C(0x93956d7478ccec8f)}, |
1938 | | {UINT64_C(0xaf58416654a6babb), UINT64_C(0x387ac8d1970027b3)}, |
1939 | | {UINT64_C(0xdb2e51bfe9d0696a), UINT64_C(0x06997b05fcc0319f)}, |
1940 | | {UINT64_C(0x88fcf317f22241e2), UINT64_C(0x441fece3bdf81f04)}, |
1941 | | {UINT64_C(0xab3c2fddeeaad25a), UINT64_C(0xd527e81cad7626c4)}, |
1942 | | {UINT64_C(0xd60b3bd56a5586f1), UINT64_C(0x8a71e223d8d3b075)}, |
1943 | | {UINT64_C(0x85c7056562757456), UINT64_C(0xf6872d5667844e4a)}, |
1944 | | {UINT64_C(0xa738c6bebb12d16c), UINT64_C(0xb428f8ac016561dc)}, |
1945 | | {UINT64_C(0xd106f86e69d785c7), UINT64_C(0xe13336d701beba53)}, |
1946 | | {UINT64_C(0x82a45b450226b39c), UINT64_C(0xecc0024661173474)}, |
1947 | | {UINT64_C(0xa34d721642b06084), UINT64_C(0x27f002d7f95d0191)}, |
1948 | | {UINT64_C(0xcc20ce9bd35c78a5), UINT64_C(0x31ec038df7b441f5)}, |
1949 | | {UINT64_C(0xff290242c83396ce), UINT64_C(0x7e67047175a15272)}, |
1950 | | {UINT64_C(0x9f79a169bd203e41), UINT64_C(0x0f0062c6e984d387)}, |
1951 | | {UINT64_C(0xc75809c42c684dd1), UINT64_C(0x52c07b78a3e60869)}, |
1952 | | {UINT64_C(0xf92e0c3537826145), UINT64_C(0xa7709a56ccdf8a83)}, |
1953 | | {UINT64_C(0x9bbcc7a142b17ccb), UINT64_C(0x88a66076400bb692)}, |
1954 | | {UINT64_C(0xc2abf989935ddbfe), UINT64_C(0x6acff893d00ea436)}, |
1955 | | {UINT64_C(0xf356f7ebf83552fe), UINT64_C(0x0583f6b8c4124d44)}, |
1956 | | {UINT64_C(0x98165af37b2153de), UINT64_C(0xc3727a337a8b704b)}, |
1957 | | {UINT64_C(0xbe1bf1b059e9a8d6), UINT64_C(0x744f18c0592e4c5d)}, |
1958 | | {UINT64_C(0xeda2ee1c7064130c), UINT64_C(0x1162def06f79df74)}, |
1959 | | {UINT64_C(0x9485d4d1c63e8be7), UINT64_C(0x8addcb5645ac2ba9)}, |
1960 | | {UINT64_C(0xb9a74a0637ce2ee1), UINT64_C(0x6d953e2bd7173693)}, |
1961 | | {UINT64_C(0xe8111c87c5c1ba99), UINT64_C(0xc8fa8db6ccdd0438)}, |
1962 | | {UINT64_C(0x910ab1d4db9914a0), UINT64_C(0x1d9c9892400a22a3)}, |
1963 | | {UINT64_C(0xb54d5e4a127f59c8), UINT64_C(0x2503beb6d00cab4c)}, |
1964 | | {UINT64_C(0xe2a0b5dc971f303a), UINT64_C(0x2e44ae64840fd61e)}, |
1965 | | {UINT64_C(0x8da471a9de737e24), UINT64_C(0x5ceaecfed289e5d3)}, |
1966 | | {UINT64_C(0xb10d8e1456105dad), UINT64_C(0x7425a83e872c5f48)}, |
1967 | | {UINT64_C(0xdd50f1996b947518), UINT64_C(0xd12f124e28f7771a)}, |
1968 | | {UINT64_C(0x8a5296ffe33cc92f), UINT64_C(0x82bd6b70d99aaa70)}, |
1969 | | {UINT64_C(0xace73cbfdc0bfb7b), UINT64_C(0x636cc64d1001550c)}, |
1970 | | {UINT64_C(0xd8210befd30efa5a), UINT64_C(0x3c47f7e05401aa4f)}, |
1971 | | {UINT64_C(0x8714a775e3e95c78), UINT64_C(0x65acfaec34810a72)}, |
1972 | | {UINT64_C(0xa8d9d1535ce3b396), UINT64_C(0x7f1839a741a14d0e)}, |
1973 | | {UINT64_C(0xd31045a8341ca07c), UINT64_C(0x1ede48111209a051)}, |
1974 | | {UINT64_C(0x83ea2b892091e44d), UINT64_C(0x934aed0aab460433)}, |
1975 | | {UINT64_C(0xa4e4b66b68b65d60), UINT64_C(0xf81da84d56178540)}, |
1976 | | {UINT64_C(0xce1de40642e3f4b9), UINT64_C(0x36251260ab9d668f)}, |
1977 | | {UINT64_C(0x80d2ae83e9ce78f3), UINT64_C(0xc1d72b7c6b42601a)}, |
1978 | | {UINT64_C(0xa1075a24e4421730), UINT64_C(0xb24cf65b8612f820)}, |
1979 | | {UINT64_C(0xc94930ae1d529cfc), UINT64_C(0xdee033f26797b628)}, |
1980 | | {UINT64_C(0xfb9b7cd9a4a7443c), UINT64_C(0x169840ef017da3b2)}, |
1981 | | {UINT64_C(0x9d412e0806e88aa5), UINT64_C(0x8e1f289560ee864f)}, |
1982 | | {UINT64_C(0xc491798a08a2ad4e), UINT64_C(0xf1a6f2bab92a27e3)}, |
1983 | | {UINT64_C(0xf5b5d7ec8acb58a2), UINT64_C(0xae10af696774b1dc)}, |
1984 | | {UINT64_C(0x9991a6f3d6bf1765), UINT64_C(0xacca6da1e0a8ef2a)}, |
1985 | | {UINT64_C(0xbff610b0cc6edd3f), UINT64_C(0x17fd090a58d32af4)}, |
1986 | | {UINT64_C(0xeff394dcff8a948e), UINT64_C(0xddfc4b4cef07f5b1)}, |
1987 | | {UINT64_C(0x95f83d0a1fb69cd9), UINT64_C(0x4abdaf101564f98f)}, |
1988 | | {UINT64_C(0xbb764c4ca7a4440f), UINT64_C(0x9d6d1ad41abe37f2)}, |
1989 | | {UINT64_C(0xea53df5fd18d5513), UINT64_C(0x84c86189216dc5ee)}, |
1990 | | {UINT64_C(0x92746b9be2f8552c), UINT64_C(0x32fd3cf5b4e49bb5)}, |
1991 | | {UINT64_C(0xb7118682dbb66a77), UINT64_C(0x3fbc8c33221dc2a2)}, |
1992 | | {UINT64_C(0xe4d5e82392a40515), UINT64_C(0x0fabaf3feaa5334b)}, |
1993 | | {UINT64_C(0x8f05b1163ba6832d), UINT64_C(0x29cb4d87f2a7400f)}, |
1994 | | {UINT64_C(0xb2c71d5bca9023f8), UINT64_C(0x743e20e9ef511013)}, |
1995 | | {UINT64_C(0xdf78e4b2bd342cf6), UINT64_C(0x914da9246b255417)}, |
1996 | | {UINT64_C(0x8bab8eefb6409c1a), UINT64_C(0x1ad089b6c2f7548f)}, |
1997 | | {UINT64_C(0xae9672aba3d0c320), UINT64_C(0xa184ac2473b529b2)}, |
1998 | | {UINT64_C(0xda3c0f568cc4f3e8), UINT64_C(0xc9e5d72d90a2741f)}, |
1999 | | {UINT64_C(0x8865899617fb1871), UINT64_C(0x7e2fa67c7a658893)}, |
2000 | | {UINT64_C(0xaa7eebfb9df9de8d), UINT64_C(0xddbb901b98feeab8)}, |
2001 | | {UINT64_C(0xd51ea6fa85785631), UINT64_C(0x552a74227f3ea566)}, |
2002 | | {UINT64_C(0x8533285c936b35de), UINT64_C(0xd53a88958f872760)}, |
2003 | | {UINT64_C(0xa67ff273b8460356), UINT64_C(0x8a892abaf368f138)}, |
2004 | | {UINT64_C(0xd01fef10a657842c), UINT64_C(0x2d2b7569b0432d86)}, |
2005 | | {UINT64_C(0x8213f56a67f6b29b), UINT64_C(0x9c3b29620e29fc74)}, |
2006 | | {UINT64_C(0xa298f2c501f45f42), UINT64_C(0x8349f3ba91b47b90)}, |
2007 | | {UINT64_C(0xcb3f2f7642717713), UINT64_C(0x241c70a936219a74)}, |
2008 | | {UINT64_C(0xfe0efb53d30dd4d7), UINT64_C(0xed238cd383aa0111)}, |
2009 | | {UINT64_C(0x9ec95d1463e8a506), UINT64_C(0xf4363804324a40ab)}, |
2010 | | {UINT64_C(0xc67bb4597ce2ce48), UINT64_C(0xb143c6053edcd0d6)}, |
2011 | | {UINT64_C(0xf81aa16fdc1b81da), UINT64_C(0xdd94b7868e94050b)}, |
2012 | | {UINT64_C(0x9b10a4e5e9913128), UINT64_C(0xca7cf2b4191c8327)}, |
2013 | | {UINT64_C(0xc1d4ce1f63f57d72), UINT64_C(0xfd1c2f611f63a3f1)}, |
2014 | | {UINT64_C(0xf24a01a73cf2dccf), UINT64_C(0xbc633b39673c8ced)}, |
2015 | | {UINT64_C(0x976e41088617ca01), UINT64_C(0xd5be0503e085d814)}, |
2016 | | {UINT64_C(0xbd49d14aa79dbc82), UINT64_C(0x4b2d8644d8a74e19)}, |
2017 | | {UINT64_C(0xec9c459d51852ba2), UINT64_C(0xddf8e7d60ed1219f)}, |
2018 | | {UINT64_C(0x93e1ab8252f33b45), UINT64_C(0xcabb90e5c942b504)}, |
2019 | | {UINT64_C(0xb8da1662e7b00a17), UINT64_C(0x3d6a751f3b936244)}, |
2020 | | {UINT64_C(0xe7109bfba19c0c9d), UINT64_C(0x0cc512670a783ad5)}, |
2021 | | {UINT64_C(0x906a617d450187e2), UINT64_C(0x27fb2b80668b24c6)}, |
2022 | | {UINT64_C(0xb484f9dc9641e9da), UINT64_C(0xb1f9f660802dedf7)}, |
2023 | | {UINT64_C(0xe1a63853bbd26451), UINT64_C(0x5e7873f8a0396974)}, |
2024 | | {UINT64_C(0x8d07e33455637eb2), UINT64_C(0xdb0b487b6423e1e9)}, |
2025 | | {UINT64_C(0xb049dc016abc5e5f), UINT64_C(0x91ce1a9a3d2cda63)}, |
2026 | | {UINT64_C(0xdc5c5301c56b75f7), UINT64_C(0x7641a140cc7810fc)}, |
2027 | | {UINT64_C(0x89b9b3e11b6329ba), UINT64_C(0xa9e904c87fcb0a9e)}, |
2028 | | {UINT64_C(0xac2820d9623bf429), UINT64_C(0x546345fa9fbdcd45)}, |
2029 | | {UINT64_C(0xd732290fbacaf133), UINT64_C(0xa97c177947ad4096)}, |
2030 | | {UINT64_C(0x867f59a9d4bed6c0), UINT64_C(0x49ed8eabcccc485e)}, |
2031 | | {UINT64_C(0xa81f301449ee8c70), UINT64_C(0x5c68f256bfff5a75)}, |
2032 | | {UINT64_C(0xd226fc195c6a2f8c), UINT64_C(0x73832eec6fff3112)}, |
2033 | | {UINT64_C(0x83585d8fd9c25db7), UINT64_C(0xc831fd53c5ff7eac)}, |
2034 | | {UINT64_C(0xa42e74f3d032f525), UINT64_C(0xba3e7ca8b77f5e56)}, |
2035 | | {UINT64_C(0xcd3a1230c43fb26f), UINT64_C(0x28ce1bd2e55f35ec)}, |
2036 | | {UINT64_C(0x80444b5e7aa7cf85), UINT64_C(0x7980d163cf5b81b4)}, |
2037 | | {UINT64_C(0xa0555e361951c366), UINT64_C(0xd7e105bcc3326220)}, |
2038 | | {UINT64_C(0xc86ab5c39fa63440), UINT64_C(0x8dd9472bf3fefaa8)}, |
2039 | | {UINT64_C(0xfa856334878fc150), UINT64_C(0xb14f98f6f0feb952)}, |
2040 | | {UINT64_C(0x9c935e00d4b9d8d2), UINT64_C(0x6ed1bf9a569f33d4)}, |
2041 | | {UINT64_C(0xc3b8358109e84f07), UINT64_C(0x0a862f80ec4700c9)}, |
2042 | | {UINT64_C(0xf4a642e14c6262c8), UINT64_C(0xcd27bb612758c0fb)}, |
2043 | | {UINT64_C(0x98e7e9cccfbd7dbd), UINT64_C(0x8038d51cb897789d)}, |
2044 | | {UINT64_C(0xbf21e44003acdd2c), UINT64_C(0xe0470a63e6bd56c4)}, |
2045 | | {UINT64_C(0xeeea5d5004981478), UINT64_C(0x1858ccfce06cac75)}, |
2046 | | {UINT64_C(0x95527a5202df0ccb), UINT64_C(0x0f37801e0c43ebc9)}, |
2047 | | {UINT64_C(0xbaa718e68396cffd), UINT64_C(0xd30560258f54e6bb)}, |
2048 | | {UINT64_C(0xe950df20247c83fd), UINT64_C(0x47c6b82ef32a206a)}, |
2049 | | {UINT64_C(0x91d28b7416cdd27e), UINT64_C(0x4cdc331d57fa5442)}, |
2050 | | {UINT64_C(0xb6472e511c81471d), UINT64_C(0xe0133fe4adf8e953)}, |
2051 | | {UINT64_C(0xe3d8f9e563a198e5), UINT64_C(0x58180fddd97723a7)}, |
2052 | | {UINT64_C(0x8e679c2f5e44ff8f), UINT64_C(0x570f09eaa7ea7649)}, |
2053 | | {UINT64_C(0xb201833b35d63f73), UINT64_C(0x2cd2cc6551e513db)}, |
2054 | | {UINT64_C(0xde81e40a034bcf4f), UINT64_C(0xf8077f7ea65e58d2)}, |
2055 | | {UINT64_C(0x8b112e86420f6191), UINT64_C(0xfb04afaf27faf783)}, |
2056 | | {UINT64_C(0xadd57a27d29339f6), UINT64_C(0x79c5db9af1f9b564)}, |
2057 | | {UINT64_C(0xd94ad8b1c7380874), UINT64_C(0x18375281ae7822bd)}, |
2058 | | {UINT64_C(0x87cec76f1c830548), UINT64_C(0x8f2293910d0b15b6)}, |
2059 | | {UINT64_C(0xa9c2794ae3a3c69a), UINT64_C(0xb2eb3875504ddb23)}, |
2060 | | {UINT64_C(0xd433179d9c8cb841), UINT64_C(0x5fa60692a46151ec)}, |
2061 | | {UINT64_C(0x849feec281d7f328), UINT64_C(0xdbc7c41ba6bcd334)}, |
2062 | | {UINT64_C(0xa5c7ea73224deff3), UINT64_C(0x12b9b522906c0801)}, |
2063 | | {UINT64_C(0xcf39e50feae16bef), UINT64_C(0xd768226b34870a01)}, |
2064 | | {UINT64_C(0x81842f29f2cce375), UINT64_C(0xe6a1158300d46641)}, |
2065 | | {UINT64_C(0xa1e53af46f801c53), UINT64_C(0x60495ae3c1097fd1)}, |
2066 | | {UINT64_C(0xca5e89b18b602368), UINT64_C(0x385bb19cb14bdfc5)}, |
2067 | | {UINT64_C(0xfcf62c1dee382c42), UINT64_C(0x46729e03dd9ed7b6)}, |
2068 | | {UINT64_C(0x9e19db92b4e31ba9), UINT64_C(0x6c07a2c26a8346d2)}, |
2069 | | {UINT64_C(0xc5a05277621be293), UINT64_C(0xc7098b7305241886)}, |
2070 | | {UINT64_C(0xf70867153aa2db38), UINT64_C(0xb8cbee4fc66d1ea8)}}}; |
2071 | | }; |
2072 | | #if !GLZ_JKJ_HAS_INLINE_VARIABLE |
2073 | | // decltype(...) should not depend on Dummy; see |
2074 | | // https://stackoverflow.com/questions/76438400/decltype-on-static-variable-in-template-class. |
2075 | | template <class Dummy> |
2076 | | constexpr decltype(cache_holder<ieee754_binary64>::cache) cache_holder<ieee754_binary64, Dummy>::cache; |
2077 | | #endif |
2078 | | |
2079 | | // Compressed cache. |
2080 | | template <class FloatFormat, class Dummy = void> |
2081 | | struct compressed_cache_holder |
2082 | | { |
2083 | | using cache_entry_type = typename cache_holder<FloatFormat>::cache_entry_type; |
2084 | | static constexpr int cache_bits = cache_holder<FloatFormat>::cache_bits; |
2085 | | static constexpr int min_k = cache_holder<FloatFormat>::min_k; |
2086 | | static constexpr int max_k = cache_holder<FloatFormat>::max_k; |
2087 | | |
2088 | | template <class ShiftAmountType, class DecimalExponentType> |
2089 | | static constexpr cache_entry_type get_cache(DecimalExponentType k) noexcept |
2090 | | { |
2091 | | return cache_holder<FloatFormat>::cache[k - min_k]; |
2092 | | } |
2093 | | }; |
2094 | | |
2095 | | template <class Dummy> |
2096 | | struct compressed_cache_holder<ieee754_binary32, Dummy> |
2097 | | { |
2098 | | using cache_entry_type = cache_holder<ieee754_binary32>::cache_entry_type; |
2099 | | static constexpr int cache_bits = cache_holder<ieee754_binary32>::cache_bits; |
2100 | | static constexpr int min_k = cache_holder<ieee754_binary32>::min_k; |
2101 | | static constexpr int max_k = cache_holder<ieee754_binary32>::max_k; |
2102 | | static constexpr int compression_ratio = 13; |
2103 | | static constexpr detail::stdr::size_t compressed_table_size = |
2104 | | detail::stdr::size_t((max_k - min_k + compression_ratio) / compression_ratio); |
2105 | | static constexpr detail::stdr::size_t pow5_table_size = detail::stdr::size_t((compression_ratio + 1) / 2); |
2106 | | |
2107 | | using cache_holder_t = detail::array<cache_entry_type, compressed_table_size>; |
2108 | | using pow5_holder_t = detail::array<detail::stdr::uint_least16_t, pow5_table_size>; |
2109 | | |
2110 | | #if GLZ_JKJ_HAS_CONSTEXPR17 |
2111 | | static constexpr cache_holder_t cache GLZ_JKJ_STATIC_DATA_SECTION = [] { |
2112 | | cache_holder_t res{}; |
2113 | | for (detail::stdr::size_t i = 0; i < compressed_table_size; ++i) { |
2114 | | res[i] = cache_holder<ieee754_binary32>::cache[i * compression_ratio]; |
2115 | | } |
2116 | | return res; |
2117 | | }(); |
2118 | | static constexpr pow5_holder_t pow5_table GLZ_JKJ_STATIC_DATA_SECTION = [] { |
2119 | | pow5_holder_t res{}; |
2120 | | detail::stdr::uint_least16_t p = 1; |
2121 | | for (detail::stdr::size_t i = 0; i < pow5_table_size; ++i) { |
2122 | | res[i] = p; |
2123 | | p *= 5; |
2124 | | } |
2125 | | return res; |
2126 | | }(); |
2127 | | #else |
2128 | | template <detail::stdr::size_t... indices> |
2129 | | static constexpr cache_holder_t make_cache(detail::index_sequence<indices...>) |
2130 | | { |
2131 | | return {cache_holder<ieee754_binary32>::cache[indices * compression_ratio]...}; |
2132 | | } |
2133 | | static constexpr cache_holder_t cache GLZ_JKJ_STATIC_DATA_SECTION = |
2134 | | make_cache(detail::make_index_sequence<compressed_table_size>{}); |
2135 | | |
2136 | | template <detail::stdr::size_t... indices> |
2137 | | static constexpr pow5_holder_t make_pow5_table(detail::index_sequence<indices...>) |
2138 | | { |
2139 | | return {detail::compute_power<indices>(detail::stdr::uint_least16_t(5))...}; |
2140 | | } |
2141 | | static constexpr pow5_holder_t pow5_table GLZ_JKJ_STATIC_DATA_SECTION = |
2142 | | make_pow5_table(detail::make_index_sequence<pow5_table_size>{}); |
2143 | | #endif |
2144 | | |
2145 | | template <class ShiftAmountType, class DecimalExponentType> |
2146 | | static GLZ_JKJ_CONSTEXPR20 cache_entry_type get_cache(DecimalExponentType k) noexcept |
2147 | | { |
2148 | | // Compute the base index. |
2149 | | // Supposed to compute (k - min_k) / compression_ratio. |
2150 | | static_assert(max_k - min_k <= 89 && compression_ratio == 13, ""); |
2151 | | static_assert(max_k - min_k <= (detail::stdr::numeric_limits<DecimalExponentType>::max)(), ""); |
2152 | | const auto cache_index = DecimalExponentType( |
2153 | | detail::stdr::uint_fast16_t(DecimalExponentType(k - min_k) * detail::stdr::int_fast16_t(79)) >> 10); |
2154 | | const auto kb = DecimalExponentType(cache_index * compression_ratio + min_k); |
2155 | | const auto offset = DecimalExponentType(k - kb); |
2156 | | |
2157 | | // Get the base cache. |
2158 | | const auto base_cache = cache[cache_index]; |
2159 | | |
2160 | | if (offset == 0) { |
2161 | | return base_cache; |
2162 | | } |
2163 | | else { |
2164 | | // Compute the required amount of bit-shift. |
2165 | | const auto alpha = ShiftAmountType(detail::log::floor_log2_pow10<min_k, max_k>(k) - |
2166 | | detail::log::floor_log2_pow10<min_k, max_k>(kb) - offset); |
2167 | | assert(alpha > 0 && alpha < 64); |
2168 | | |
2169 | | // Try to recover the real cache. |
2170 | | const auto pow5 = |
2171 | | offset >= 7 |
2172 | | ? detail::stdr::uint_fast32_t(detail::stdr::uint_fast32_t(pow5_table[6]) * pow5_table[offset - 6]) |
2173 | | : detail::stdr::uint_fast32_t(pow5_table[offset]); |
2174 | | auto mul_result = detail::wuint::umul128(base_cache, pow5); |
2175 | | const auto recovered_cache = cache_entry_type( |
2176 | | (((mul_result.high() << ShiftAmountType(64 - alpha)) | (mul_result.low() >> alpha)) + 1) & |
2177 | | UINT64_C(0xffffffffffffffff)); |
2178 | | assert(recovered_cache != 0); |
2179 | | |
2180 | | return recovered_cache; |
2181 | | } |
2182 | | } |
2183 | | }; |
2184 | | #if !GLZ_JKJ_HAS_INLINE_VARIABLE |
2185 | | template <class Dummy> |
2186 | | constexpr typename compressed_cache_holder<ieee754_binary32, Dummy>::cache_holder_t |
2187 | | compressed_cache_holder<ieee754_binary32, Dummy>::cache; |
2188 | | template <class Dummy> |
2189 | | constexpr typename compressed_cache_holder<ieee754_binary32, Dummy>::pow5_holder_t |
2190 | | compressed_cache_holder<ieee754_binary32, Dummy>::pow5_table; |
2191 | | #endif |
2192 | | |
2193 | | template <class Dummy> |
2194 | | struct compressed_cache_holder<ieee754_binary64, Dummy> |
2195 | | { |
2196 | | using cache_entry_type = cache_holder<ieee754_binary64>::cache_entry_type; |
2197 | | static constexpr int cache_bits = cache_holder<ieee754_binary64>::cache_bits; |
2198 | | static constexpr int min_k = cache_holder<ieee754_binary64>::min_k; |
2199 | | static constexpr int max_k = cache_holder<ieee754_binary64>::max_k; |
2200 | | static constexpr int compression_ratio = 27; |
2201 | | static constexpr detail::stdr::size_t compressed_table_size = |
2202 | | detail::stdr::size_t((max_k - min_k + compression_ratio) / compression_ratio); |
2203 | | static constexpr detail::stdr::size_t pow5_table_size = detail::stdr::size_t(compression_ratio); |
2204 | | |
2205 | | using cache_holder_t = detail::array<cache_entry_type, compressed_table_size>; |
2206 | | using pow5_holder_t = detail::array<detail::stdr::uint_least64_t, pow5_table_size>; |
2207 | | |
2208 | | #if GLZ_JKJ_HAS_CONSTEXPR17 |
2209 | | static constexpr cache_holder_t cache GLZ_JKJ_STATIC_DATA_SECTION = [] { |
2210 | | cache_holder_t res{}; |
2211 | | for (detail::stdr::size_t i = 0; i < compressed_table_size; ++i) { |
2212 | | res[i] = cache_holder<ieee754_binary64>::cache[i * compression_ratio]; |
2213 | | } |
2214 | | return res; |
2215 | | }(); |
2216 | | static constexpr pow5_holder_t pow5_table GLZ_JKJ_STATIC_DATA_SECTION = [] { |
2217 | | pow5_holder_t res{}; |
2218 | | detail::stdr::uint_least64_t p = 1; |
2219 | | for (detail::stdr::size_t i = 0; i < pow5_table_size; ++i) { |
2220 | | res[i] = p; |
2221 | | p *= 5; |
2222 | | } |
2223 | | return res; |
2224 | | }(); |
2225 | | #else |
2226 | | template <detail::stdr::size_t... indices> |
2227 | | static constexpr cache_holder_t make_cache(detail::index_sequence<indices...>) |
2228 | | { |
2229 | | return {cache_holder<ieee754_binary64>::cache[indices * compression_ratio]...}; |
2230 | | } |
2231 | | static constexpr cache_holder_t cache GLZ_JKJ_STATIC_DATA_SECTION = |
2232 | | make_cache(detail::make_index_sequence<compressed_table_size>{}); |
2233 | | |
2234 | | template <detail::stdr::size_t... indices> |
2235 | | static constexpr pow5_holder_t make_pow5_table(detail::index_sequence<indices...>) |
2236 | | { |
2237 | | return {detail::compute_power<indices>(detail::stdr::uint_least64_t(5))...}; |
2238 | | } |
2239 | | static constexpr pow5_holder_t pow5_table GLZ_JKJ_STATIC_DATA_SECTION = |
2240 | | make_pow5_table(detail::make_index_sequence<pow5_table_size>{}); |
2241 | | #endif |
2242 | | |
2243 | | template <class ShiftAmountType, class DecimalExponentType> |
2244 | | static GLZ_JKJ_CONSTEXPR20 cache_entry_type get_cache(DecimalExponentType k) noexcept |
2245 | | { |
2246 | | // Compute the base index. |
2247 | | // Supposed to compute (k - min_k) / compression_ratio. |
2248 | | static_assert(max_k - min_k <= 619 && compression_ratio == 27, ""); |
2249 | | static_assert(max_k - min_k <= (detail::stdr::numeric_limits<DecimalExponentType>::max)(), ""); |
2250 | | const auto cache_index = DecimalExponentType( |
2251 | | detail::stdr::uint_fast32_t(DecimalExponentType(k - min_k) * detail::stdr::int_fast32_t(607)) >> 14); |
2252 | | const auto kb = DecimalExponentType(cache_index * compression_ratio + min_k); |
2253 | | const auto offset = DecimalExponentType(k - kb); |
2254 | | |
2255 | | // Get the base cache. |
2256 | | const auto base_cache = cache[cache_index]; |
2257 | | |
2258 | | if (offset == 0) { |
2259 | | return base_cache; |
2260 | | } |
2261 | | else { |
2262 | | // Compute the required amount of bit-shift. |
2263 | | const auto alpha = ShiftAmountType(detail::log::floor_log2_pow10<min_k, max_k>(k) - |
2264 | | detail::log::floor_log2_pow10<min_k, max_k>(kb) - offset); |
2265 | | assert(alpha > 0 && alpha < 64); |
2266 | | |
2267 | | // Try to recover the real cache. |
2268 | | const auto pow5 = pow5_table[offset]; |
2269 | | auto recovered_cache = detail::wuint::umul128(base_cache.high(), pow5); |
2270 | | const auto middle_low = detail::wuint::umul128(base_cache.low(), pow5); |
2271 | | |
2272 | | recovered_cache += middle_low.high(); |
2273 | | |
2274 | | const auto high_to_middle = detail::stdr::uint_least64_t( |
2275 | | (recovered_cache.high() << ShiftAmountType(64 - alpha)) & UINT64_C(0xffffffffffffffff)); |
2276 | | const auto middle_to_low = detail::stdr::uint_least64_t( |
2277 | | (recovered_cache.low() << ShiftAmountType(64 - alpha)) & UINT64_C(0xffffffffffffffff)); |
2278 | | |
2279 | | recovered_cache = {(recovered_cache.low() >> alpha) | high_to_middle, |
2280 | | ((middle_low.low() >> alpha) | middle_to_low)}; |
2281 | | |
2282 | | assert(recovered_cache.low() != UINT64_C(0xffffffffffffffff)); |
2283 | | recovered_cache = {recovered_cache.high(), detail::stdr::uint_least64_t(recovered_cache.low() + 1)}; |
2284 | | |
2285 | | return recovered_cache; |
2286 | | } |
2287 | | } |
2288 | | }; |
2289 | | #if !GLZ_JKJ_HAS_INLINE_VARIABLE |
2290 | | template <class Dummy> |
2291 | | constexpr typename compressed_cache_holder<ieee754_binary64, Dummy>::cache_holder_t |
2292 | | compressed_cache_holder<ieee754_binary64, Dummy>::cache; |
2293 | | template <class Dummy> |
2294 | | constexpr typename compressed_cache_holder<ieee754_binary64, Dummy>::pow5_holder_t |
2295 | | compressed_cache_holder<ieee754_binary64, Dummy>::pow5_table; |
2296 | | #endif |
2297 | | |
2298 | | //////////////////////////////////////////////////////////////////////////////////////// |
2299 | | // Forward declarations of user-specializable templates used in the main algorithm. |
2300 | | //////////////////////////////////////////////////////////////////////////////////////// |
2301 | | |
2302 | | // Remove trailing zeros from significand and add the number of removed zeros into |
2303 | | // exponent. |
2304 | | template <class TrailingZeroPolicy, class Format, class DecimalSignificand, class DecimalExponentType> |
2305 | | struct remove_trailing_zeros_traits; |
2306 | | |
2307 | | // Users can specialize this traits class to make Dragonbox work with their own formats. |
2308 | | // However, this requires detailed knowledge on how the algorithm works, so it is recommended to |
2309 | | // read through the paper. |
2310 | | template <class FormatTraits, class CacheEntryType, detail::stdr::size_t cache_bits_> |
2311 | | struct multiplication_traits; |
2312 | | |
2313 | | // A collection of some common definitions to reduce boilerplate. |
2314 | | template <class FormatTraits, class CacheEntryType, detail::stdr::size_t cache_bits_> |
2315 | | struct multiplication_traits_base |
2316 | | { |
2317 | | using format = typename FormatTraits::format; |
2318 | | static constexpr int significand_bits = format::significand_bits; |
2319 | | static constexpr int total_bits = format::total_bits; |
2320 | | using carrier_uint = typename FormatTraits::carrier_uint; |
2321 | | using cache_entry_type = CacheEntryType; |
2322 | | static constexpr int cache_bits = int(cache_bits_); |
2323 | | |
2324 | | struct compute_mul_result |
2325 | | { |
2326 | | carrier_uint integer_part; |
2327 | | bool is_integer; |
2328 | | }; |
2329 | | struct compute_mul_parity_result |
2330 | | { |
2331 | | bool parity; |
2332 | | bool is_integer; |
2333 | | }; |
2334 | | }; |
2335 | | |
2336 | | //////////////////////////////////////////////////////////////////////////////////////// |
2337 | | // Policies. |
2338 | | //////////////////////////////////////////////////////////////////////////////////////// |
2339 | | |
2340 | | namespace detail |
2341 | | { |
2342 | | template <class T> |
2343 | | struct dummy |
2344 | | {}; |
2345 | | } |
2346 | | |
2347 | | namespace policy |
2348 | | { |
2349 | | namespace sign |
2350 | | { |
2351 | | GLZ_JKJ_INLINE_VARIABLE struct ignore_t |
2352 | | { |
2353 | | using sign_policy = ignore_t; |
2354 | | static constexpr bool return_has_sign = false; |
2355 | | |
2356 | | #if defined(_MSC_VER) && !defined(__clang__) |
2357 | | // See |
2358 | | // https://developercommunity.visualstudio.com/t/Failure-to-optimize-intrinsics/10628226 |
2359 | | template <class SignedSignificandBits, class DecimalSignificand, class DecimalExponentType> |
2360 | | static constexpr decimal_fp<DecimalSignificand, DecimalExponentType, false, false> handle_sign( |
2361 | | SignedSignificandBits, decimal_fp<DecimalSignificand, DecimalExponentType, false, false> r) noexcept |
2362 | | { |
2363 | | return {r.significand, r.exponent}; |
2364 | | } |
2365 | | template <class SignedSignificandBits, class DecimalSignificand, class DecimalExponentType> |
2366 | | static constexpr decimal_fp<DecimalSignificand, DecimalExponentType, false, true> handle_sign( |
2367 | | SignedSignificandBits, decimal_fp<DecimalSignificand, DecimalExponentType, false, true> r) noexcept |
2368 | | { |
2369 | | return {r.significand, r.exponent, r.may_have_trailing_zeros}; |
2370 | | } |
2371 | | #else |
2372 | | template <class SignedSignificandBits, class UnsignedDecimalFp> |
2373 | | static constexpr UnsignedDecimalFp handle_sign(SignedSignificandBits, UnsignedDecimalFp r) noexcept |
2374 | 0 | { |
2375 | 0 | return r; |
2376 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::decimal_fp<unsigned long, int, false, false> glz::jkj::dragonbox::policy::sign::ignore_t::handle_sign<glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >, glz::jkj::dragonbox::decimal_fp<unsigned long, int, false, false> >(glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >, glz::jkj::dragonbox::decimal_fp<unsigned long, int, false, false>) Unexecuted instantiation: glz::jkj::dragonbox::decimal_fp<unsigned int, int, false, false> glz::jkj::dragonbox::policy::sign::ignore_t::handle_sign<glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >, glz::jkj::dragonbox::decimal_fp<unsigned int, int, false, false> >(glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >, glz::jkj::dragonbox::decimal_fp<unsigned int, int, false, false>) |
2377 | | #endif |
2378 | | } ignore = {}; |
2379 | | |
2380 | | GLZ_JKJ_INLINE_VARIABLE struct return_sign_t |
2381 | | { |
2382 | | using sign_policy = return_sign_t; |
2383 | | static constexpr bool return_has_sign = true; |
2384 | | |
2385 | | template <class SignedSignificandBits, class UnsignedDecimalFp> |
2386 | | static constexpr detail::unsigned_decimal_fp_to_signed_t<UnsignedDecimalFp> handle_sign( |
2387 | | SignedSignificandBits s, UnsignedDecimalFp r) noexcept |
2388 | | { |
2389 | | return add_sign_to_unsigned_decimal_fp(s.is_negative(), r); |
2390 | | } |
2391 | | } return_sign = {}; |
2392 | | } |
2393 | | |
2394 | | namespace trailing_zero |
2395 | | { |
2396 | | GLZ_JKJ_INLINE_VARIABLE struct ignore_t |
2397 | | { |
2398 | | using trailing_zero_policy = ignore_t; |
2399 | | static constexpr bool report_trailing_zeros = false; |
2400 | | |
2401 | | template <class Format, class DecimalSignificand, class DecimalExponentType> |
2402 | | static constexpr unsigned_decimal_fp<DecimalSignificand, DecimalExponentType, false> on_trailing_zeros( |
2403 | | DecimalSignificand significand, DecimalExponentType exponent) noexcept |
2404 | 0 | { |
2405 | 0 | return {significand, exponent}; |
2406 | 0 | } |
2407 | | |
2408 | | template <class Format, class DecimalSignificand, class DecimalExponentType> |
2409 | | static constexpr unsigned_decimal_fp<DecimalSignificand, DecimalExponentType, false> no_trailing_zeros( |
2410 | | DecimalSignificand significand, DecimalExponentType exponent) noexcept |
2411 | 0 | { |
2412 | 0 | return {significand, exponent}; |
2413 | 0 | } |
2414 | | } ignore = {}; |
2415 | | |
2416 | | GLZ_JKJ_INLINE_VARIABLE struct remove_t |
2417 | | { |
2418 | | using trailing_zero_policy = remove_t; |
2419 | | static constexpr bool report_trailing_zeros = false; |
2420 | | |
2421 | | template <class Format, class DecimalSignificand, class DecimalExponentType> |
2422 | | GLZ_JKJ_FORCEINLINE static GLZ_JKJ_CONSTEXPR14 |
2423 | | unsigned_decimal_fp<DecimalSignificand, DecimalExponentType, false> |
2424 | | on_trailing_zeros(DecimalSignificand significand, DecimalExponentType exponent) noexcept |
2425 | 0 | { |
2426 | 0 | remove_trailing_zeros_traits<remove_t, Format, DecimalSignificand, |
2427 | 0 | DecimalExponentType>::remove_trailing_zeros(significand, exponent); |
2428 | 0 | return {significand, exponent}; |
2429 | 0 | } |
2430 | | |
2431 | | template <class Format, class DecimalSignificand, class DecimalExponentType> |
2432 | | static constexpr unsigned_decimal_fp<DecimalSignificand, DecimalExponentType, false> no_trailing_zeros( |
2433 | | DecimalSignificand significand, DecimalExponentType exponent) noexcept |
2434 | 0 | { |
2435 | 0 | return {significand, exponent}; |
2436 | 0 | } |
2437 | | } remove = {}; |
2438 | | |
2439 | | GLZ_JKJ_INLINE_VARIABLE struct remove_compact_t |
2440 | | { |
2441 | | using trailing_zero_policy = remove_compact_t; |
2442 | | static constexpr bool report_trailing_zeros = false; |
2443 | | |
2444 | | template <class Format, class DecimalSignificand, class DecimalExponentType> |
2445 | | GLZ_JKJ_FORCEINLINE static GLZ_JKJ_CONSTEXPR14 |
2446 | | unsigned_decimal_fp<DecimalSignificand, DecimalExponentType, false> |
2447 | | on_trailing_zeros(DecimalSignificand significand, DecimalExponentType exponent) noexcept |
2448 | | { |
2449 | | remove_trailing_zeros_traits<remove_compact_t, Format, DecimalSignificand, |
2450 | | DecimalExponentType>::remove_trailing_zeros(significand, exponent); |
2451 | | return {significand, exponent}; |
2452 | | } |
2453 | | |
2454 | | template <class Format, class DecimalSignificand, class DecimalExponentType> |
2455 | | static constexpr unsigned_decimal_fp<DecimalSignificand, DecimalExponentType, false> no_trailing_zeros( |
2456 | | DecimalSignificand significand, DecimalExponentType exponent) noexcept |
2457 | | { |
2458 | | return {significand, exponent}; |
2459 | | } |
2460 | | } remove_compact = {}; |
2461 | | |
2462 | | GLZ_JKJ_INLINE_VARIABLE struct report_t |
2463 | | { |
2464 | | using trailing_zero_policy = report_t; |
2465 | | static constexpr bool report_trailing_zeros = true; |
2466 | | |
2467 | | template <class Format, class DecimalSignificand, class DecimalExponentType> |
2468 | | static constexpr unsigned_decimal_fp<DecimalSignificand, DecimalExponentType, true> on_trailing_zeros( |
2469 | | DecimalSignificand significand, DecimalExponentType exponent) noexcept |
2470 | | { |
2471 | | return {significand, exponent, true}; |
2472 | | } |
2473 | | |
2474 | | template <class Format, class DecimalSignificand, class DecimalExponentType> |
2475 | | static constexpr unsigned_decimal_fp<DecimalSignificand, DecimalExponentType, true> no_trailing_zeros( |
2476 | | DecimalSignificand significand, DecimalExponentType exponent) noexcept |
2477 | | { |
2478 | | return {significand, exponent, false}; |
2479 | | } |
2480 | | } report = {}; |
2481 | | } |
2482 | | |
2483 | | namespace decimal_to_binary_rounding |
2484 | | { |
2485 | | enum class tag_t { to_nearest, left_closed_directed, right_closed_directed }; |
2486 | | |
2487 | | namespace interval_type |
2488 | | { |
2489 | | struct symmetric_boundary |
2490 | | { |
2491 | | static constexpr bool is_symmetric = true; |
2492 | | bool is_closed; |
2493 | 0 | constexpr bool include_left_endpoint() const noexcept { return is_closed; } |
2494 | 0 | constexpr bool include_right_endpoint() const noexcept { return is_closed; } |
2495 | | }; |
2496 | | struct asymmetric_boundary |
2497 | | { |
2498 | | static constexpr bool is_symmetric = false; |
2499 | | bool is_left_closed; |
2500 | 0 | constexpr bool include_left_endpoint() const noexcept { return is_left_closed; } |
2501 | 0 | constexpr bool include_right_endpoint() const noexcept { return !is_left_closed; } |
2502 | | }; |
2503 | | struct closed |
2504 | | { |
2505 | | static constexpr bool is_symmetric = true; |
2506 | 0 | static constexpr bool include_left_endpoint() noexcept { return true; } |
2507 | 0 | static constexpr bool include_right_endpoint() noexcept { return true; } |
2508 | | }; |
2509 | | struct open |
2510 | | { |
2511 | | static constexpr bool is_symmetric = true; |
2512 | 0 | static constexpr bool include_left_endpoint() noexcept { return false; } |
2513 | 0 | static constexpr bool include_right_endpoint() noexcept { return false; } |
2514 | | }; |
2515 | | struct left_closed_right_open |
2516 | | { |
2517 | | static constexpr bool is_symmetric = false; |
2518 | 0 | static constexpr bool include_left_endpoint() noexcept { return true; } |
2519 | 0 | static constexpr bool include_right_endpoint() noexcept { return false; } |
2520 | | }; |
2521 | | struct right_closed_left_open |
2522 | | { |
2523 | | static constexpr bool is_symmetric = false; |
2524 | 0 | static constexpr bool include_left_endpoint() noexcept { return false; } |
2525 | 0 | static constexpr bool include_right_endpoint() noexcept { return true; } |
2526 | | }; |
2527 | | } |
2528 | | |
2529 | | GLZ_JKJ_INLINE_VARIABLE struct nearest_to_even_t |
2530 | | { |
2531 | | using decimal_to_binary_rounding_policy = nearest_to_even_t; |
2532 | | using interval_type_provider = nearest_to_even_t; |
2533 | | static constexpr auto tag = tag_t::to_nearest; |
2534 | | |
2535 | | template <class SignedSignificandBits, class Func, class... Args> |
2536 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static constexpr decltype(Func{}( |
2537 | | dragonbox::detail::declval<nearest_to_even_t>(), Args{}...)) |
2538 | | delegate(SignedSignificandBits, Func f, Args... args) noexcept |
2539 | 0 | { |
2540 | 0 | return f(nearest_to_even_t{}, args...); |
2541 | 0 | } Unexecuted instantiation: decltype (glz::jkj::dragonbox::detail::to_decimal_dispatcher<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int>, glz::jkj::dragonbox::detail::policy_holder<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::ignore_t, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t, glz::jkj::dragonbox::policy::cache::full_t, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >{}((glz::jkj::dragonbox::detail::declval<glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>)(), glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >{}, int{})) glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t::delegate<glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >, glz::jkj::dragonbox::detail::to_decimal_dispatcher<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int>, glz::jkj::dragonbox::detail::policy_holder<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::ignore_t, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t, glz::jkj::dragonbox::policy::cache::full_t, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >, int>(glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >, glz::jkj::dragonbox::detail::to_decimal_dispatcher<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int>, glz::jkj::dragonbox::detail::policy_holder<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::ignore_t, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t, glz::jkj::dragonbox::policy::cache::full_t, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >, int) Unexecuted instantiation: decltype (glz::jkj::dragonbox::detail::to_decimal_dispatcher<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int>, glz::jkj::dragonbox::detail::policy_holder<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::remove_t, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t, glz::jkj::dragonbox::policy::cache::full_t, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >{}((glz::jkj::dragonbox::detail::declval<glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>)(), glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >{}, int{})) glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t::delegate<glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >, glz::jkj::dragonbox::detail::to_decimal_dispatcher<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int>, glz::jkj::dragonbox::detail::policy_holder<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::remove_t, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t, glz::jkj::dragonbox::policy::cache::full_t, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >, int>(glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >, glz::jkj::dragonbox::detail::to_decimal_dispatcher<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int>, glz::jkj::dragonbox::detail::policy_holder<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::remove_t, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t, glz::jkj::dragonbox::policy::cache::full_t, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >, int) |
2542 | | |
2543 | | template <class SignedSignificandBits> |
2544 | | static constexpr interval_type::symmetric_boundary normal_interval(SignedSignificandBits s) noexcept |
2545 | 0 | { |
2546 | 0 | return {s.has_even_significand_bits()}; |
2547 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::policy::decimal_to_binary_rounding::interval_type::symmetric_boundary glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t::normal_interval<glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> > >(glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >) Unexecuted instantiation: glz::jkj::dragonbox::policy::decimal_to_binary_rounding::interval_type::symmetric_boundary glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t::normal_interval<glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> > >(glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >) |
2548 | | |
2549 | | template <class SignedSignificandBits> |
2550 | | static constexpr interval_type::closed shorter_interval(SignedSignificandBits) noexcept |
2551 | 0 | { |
2552 | 0 | return {}; |
2553 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::policy::decimal_to_binary_rounding::interval_type::closed glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t::shorter_interval<glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> > >(glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >) Unexecuted instantiation: glz::jkj::dragonbox::policy::decimal_to_binary_rounding::interval_type::closed glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t::shorter_interval<glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> > >(glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >) |
2554 | | } nearest_to_even = {}; |
2555 | | |
2556 | | GLZ_JKJ_INLINE_VARIABLE struct nearest_to_odd_t |
2557 | | { |
2558 | | using decimal_to_binary_rounding_policy = nearest_to_odd_t; |
2559 | | using interval_type_provider = nearest_to_odd_t; |
2560 | | static constexpr auto tag = tag_t::to_nearest; |
2561 | | |
2562 | | template <class SignedSignificandBits, class Func, class... Args> |
2563 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static constexpr decltype(Func{}( |
2564 | | dragonbox::detail::declval<nearest_to_odd_t>(), Args{}...)) |
2565 | | delegate(SignedSignificandBits, Func f, Args... args) noexcept |
2566 | | { |
2567 | | return f(nearest_to_odd_t{}, args...); |
2568 | | } |
2569 | | |
2570 | | template <class SignedSignificandBits> |
2571 | | static constexpr interval_type::symmetric_boundary normal_interval(SignedSignificandBits s) noexcept |
2572 | | { |
2573 | | return {!s.has_even_significand_bits()}; |
2574 | | } |
2575 | | template <class SignedSignificandBits> |
2576 | | static constexpr interval_type::open shorter_interval(SignedSignificandBits) noexcept |
2577 | | { |
2578 | | return {}; |
2579 | | } |
2580 | | } nearest_to_odd = {}; |
2581 | | |
2582 | | GLZ_JKJ_INLINE_VARIABLE struct nearest_toward_plus_infinity_t |
2583 | | { |
2584 | | using decimal_to_binary_rounding_policy = nearest_toward_plus_infinity_t; |
2585 | | using interval_type_provider = nearest_toward_plus_infinity_t; |
2586 | | static constexpr auto tag = tag_t::to_nearest; |
2587 | | |
2588 | | template <class SignedSignificandBits, class Func, class... Args> |
2589 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static constexpr decltype(Func{}( |
2590 | | dragonbox::detail::declval<nearest_toward_plus_infinity_t>(), Args{}...)) |
2591 | | delegate(SignedSignificandBits, Func f, Args... args) noexcept |
2592 | | { |
2593 | | return f(nearest_toward_plus_infinity_t{}, args...); |
2594 | | } |
2595 | | |
2596 | | template <class SignedSignificandBits> |
2597 | | static constexpr interval_type::asymmetric_boundary normal_interval(SignedSignificandBits s) noexcept |
2598 | | { |
2599 | | return {!s.is_negative()}; |
2600 | | } |
2601 | | template <class SignedSignificandBits> |
2602 | | static constexpr interval_type::asymmetric_boundary shorter_interval(SignedSignificandBits s) noexcept |
2603 | | { |
2604 | | return {!s.is_negative()}; |
2605 | | } |
2606 | | } nearest_toward_plus_infinity = {}; |
2607 | | |
2608 | | GLZ_JKJ_INLINE_VARIABLE struct nearest_toward_minus_infinity_t |
2609 | | { |
2610 | | using decimal_to_binary_rounding_policy = nearest_toward_minus_infinity_t; |
2611 | | using interval_type_provider = nearest_toward_minus_infinity_t; |
2612 | | static constexpr auto tag = tag_t::to_nearest; |
2613 | | |
2614 | | template <class SignedSignificandBits, class Func, class... Args> |
2615 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static constexpr decltype(Func{}( |
2616 | | dragonbox::detail::declval<nearest_toward_minus_infinity_t>(), Args{}...)) |
2617 | | delegate(SignedSignificandBits, Func f, Args... args) noexcept |
2618 | | { |
2619 | | return f(nearest_toward_minus_infinity_t{}, args...); |
2620 | | } |
2621 | | |
2622 | | template <class SignedSignificandBits> |
2623 | | static constexpr interval_type::asymmetric_boundary normal_interval(SignedSignificandBits s) noexcept |
2624 | | { |
2625 | | return {s.is_negative()}; |
2626 | | } |
2627 | | template <class SignedSignificandBits> |
2628 | | static constexpr interval_type::asymmetric_boundary shorter_interval(SignedSignificandBits s) noexcept |
2629 | | { |
2630 | | return {s.is_negative()}; |
2631 | | } |
2632 | | } nearest_toward_minus_infinity = {}; |
2633 | | |
2634 | | GLZ_JKJ_INLINE_VARIABLE struct nearest_toward_zero_t |
2635 | | { |
2636 | | using decimal_to_binary_rounding_policy = nearest_toward_zero_t; |
2637 | | using interval_type_provider = nearest_toward_zero_t; |
2638 | | static constexpr auto tag = tag_t::to_nearest; |
2639 | | |
2640 | | template <class SignedSignificandBits, class Func, class... Args> |
2641 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static constexpr decltype(Func{}( |
2642 | | dragonbox::detail::declval<nearest_toward_zero_t>(), Args{}...)) |
2643 | | delegate(SignedSignificandBits, Func f, Args... args) noexcept |
2644 | | { |
2645 | | return f(nearest_toward_zero_t{}, args...); |
2646 | | } |
2647 | | |
2648 | | template <class SignedSignificandBits> |
2649 | | static constexpr interval_type::right_closed_left_open normal_interval(SignedSignificandBits) noexcept |
2650 | | { |
2651 | | return {}; |
2652 | | } |
2653 | | template <class SignedSignificandBits> |
2654 | | static constexpr interval_type::right_closed_left_open shorter_interval(SignedSignificandBits) noexcept |
2655 | | { |
2656 | | return {}; |
2657 | | } |
2658 | | } nearest_toward_zero = {}; |
2659 | | |
2660 | | GLZ_JKJ_INLINE_VARIABLE struct nearest_away_from_zero_t |
2661 | | { |
2662 | | using decimal_to_binary_rounding_policy = nearest_away_from_zero_t; |
2663 | | using interval_type_provider = nearest_away_from_zero_t; |
2664 | | static constexpr auto tag = tag_t::to_nearest; |
2665 | | |
2666 | | template <class SignedSignificandBits, class Func, class... Args> |
2667 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static constexpr decltype(Func{}( |
2668 | | dragonbox::detail::declval<nearest_away_from_zero_t>(), Args{}...)) |
2669 | | delegate(SignedSignificandBits, Func f, Args... args) noexcept |
2670 | | { |
2671 | | return f(nearest_away_from_zero_t{}, args...); |
2672 | | } |
2673 | | |
2674 | | template <class SignedSignificandBits> |
2675 | | static constexpr interval_type::left_closed_right_open normal_interval(SignedSignificandBits) noexcept |
2676 | | { |
2677 | | return {}; |
2678 | | } |
2679 | | template <class SignedSignificandBits> |
2680 | | static constexpr interval_type::left_closed_right_open shorter_interval(SignedSignificandBits) noexcept |
2681 | | { |
2682 | | return {}; |
2683 | | } |
2684 | | } nearest_away_from_zero = {}; |
2685 | | |
2686 | | namespace detail |
2687 | | { |
2688 | | struct nearest_always_closed_t |
2689 | | { |
2690 | | using interval_type_provider = nearest_always_closed_t; |
2691 | | static constexpr auto tag = tag_t::to_nearest; |
2692 | | |
2693 | | template <class SignedSignificandBits> |
2694 | | static constexpr interval_type::closed normal_interval(SignedSignificandBits) noexcept |
2695 | | { |
2696 | | return {}; |
2697 | | } |
2698 | | template <class SignedSignificandBits> |
2699 | | static constexpr interval_type::closed shorter_interval(SignedSignificandBits) noexcept |
2700 | | { |
2701 | | return {}; |
2702 | | } |
2703 | | }; |
2704 | | struct nearest_always_open_t |
2705 | | { |
2706 | | using interval_type_provider = nearest_always_open_t; |
2707 | | static constexpr auto tag = tag_t::to_nearest; |
2708 | | |
2709 | | template <class SignedSignificandBits> |
2710 | | static constexpr interval_type::open normal_interval(SignedSignificandBits) noexcept |
2711 | | { |
2712 | | return {}; |
2713 | | } |
2714 | | template <class SignedSignificandBits> |
2715 | | static constexpr interval_type::open shorter_interval(SignedSignificandBits) noexcept |
2716 | | { |
2717 | | return {}; |
2718 | | } |
2719 | | }; |
2720 | | } |
2721 | | |
2722 | | GLZ_JKJ_INLINE_VARIABLE struct nearest_to_even_static_boundary_t |
2723 | | { |
2724 | | using decimal_to_binary_rounding_policy = nearest_to_even_static_boundary_t; |
2725 | | |
2726 | | template <class SignedSignificandBits, class Func, class... Args> |
2727 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static constexpr decltype(Func{}( |
2728 | | detail::nearest_always_closed_t{}, Args{}...)) |
2729 | | delegate(SignedSignificandBits s, Func f, Args... args) noexcept |
2730 | | { |
2731 | | return s.has_even_significand_bits() ? f(detail::nearest_always_closed_t{}, args...) |
2732 | | : f(detail::nearest_always_open_t{}, args...); |
2733 | | } |
2734 | | } nearest_to_even_static_boundary = {}; |
2735 | | |
2736 | | GLZ_JKJ_INLINE_VARIABLE struct nearest_to_odd_static_boundary_t |
2737 | | { |
2738 | | using decimal_to_binary_rounding_policy = nearest_to_odd_static_boundary_t; |
2739 | | |
2740 | | template <class SignedSignificandBits, class Func, class... Args> |
2741 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static constexpr decltype(Func{}( |
2742 | | detail::nearest_always_closed_t{}, Args{}...)) |
2743 | | delegate(SignedSignificandBits s, Func f, Args... args) noexcept |
2744 | | { |
2745 | | return s.has_even_significand_bits() ? f(detail::nearest_always_open_t{}, args...) |
2746 | | : f(detail::nearest_always_closed_t{}, args...); |
2747 | | } |
2748 | | } nearest_to_odd_static_boundary = {}; |
2749 | | |
2750 | | GLZ_JKJ_INLINE_VARIABLE struct nearest_toward_plus_infinity_static_boundary_t |
2751 | | { |
2752 | | using decimal_to_binary_rounding_policy = nearest_toward_plus_infinity_static_boundary_t; |
2753 | | |
2754 | | template <class SignedSignificandBits, class Func, class... Args> |
2755 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static constexpr decltype(Func{}(nearest_toward_zero, Args{}...)) |
2756 | | delegate(SignedSignificandBits s, Func f, Args... args) noexcept |
2757 | | { |
2758 | | return s.is_negative() ? f(nearest_toward_zero, args...) : f(nearest_away_from_zero, args...); |
2759 | | } |
2760 | | } nearest_toward_plus_infinity_static_boundary = {}; |
2761 | | |
2762 | | GLZ_JKJ_INLINE_VARIABLE struct nearest_toward_minus_infinity_static_boundary_t |
2763 | | { |
2764 | | using decimal_to_binary_rounding_policy = nearest_toward_minus_infinity_static_boundary_t; |
2765 | | |
2766 | | template <class SignedSignificandBits, class Func, class... Args> |
2767 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static constexpr decltype(Func{}(nearest_toward_zero, Args{}...)) |
2768 | | delegate(SignedSignificandBits s, Func f, Args... args) noexcept |
2769 | | { |
2770 | | return s.is_negative() ? f(nearest_away_from_zero, args...) : f(nearest_toward_zero, args...); |
2771 | | } |
2772 | | } nearest_toward_minus_infinity_static_boundary = {}; |
2773 | | |
2774 | | namespace detail |
2775 | | { |
2776 | | struct left_closed_directed_t |
2777 | | { |
2778 | | static constexpr auto tag = tag_t::left_closed_directed; |
2779 | | }; |
2780 | | struct right_closed_directed_t |
2781 | | { |
2782 | | static constexpr auto tag = tag_t::right_closed_directed; |
2783 | | }; |
2784 | | } |
2785 | | |
2786 | | GLZ_JKJ_INLINE_VARIABLE struct toward_plus_infinity_t |
2787 | | { |
2788 | | using decimal_to_binary_rounding_policy = toward_plus_infinity_t; |
2789 | | |
2790 | | template <class SignedSignificandBits, class Func, class... Args> |
2791 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static constexpr decltype(Func{}( |
2792 | | detail::left_closed_directed_t{}, Args{}...)) |
2793 | | delegate(SignedSignificandBits s, Func f, Args... args) noexcept |
2794 | | { |
2795 | | return s.is_negative() ? f(detail::left_closed_directed_t{}, args...) |
2796 | | : f(detail::right_closed_directed_t{}, args...); |
2797 | | } |
2798 | | } toward_plus_infinity = {}; |
2799 | | |
2800 | | GLZ_JKJ_INLINE_VARIABLE struct toward_minus_infinity_t |
2801 | | { |
2802 | | using decimal_to_binary_rounding_policy = toward_minus_infinity_t; |
2803 | | |
2804 | | template <class SignedSignificandBits, class Func, class... Args> |
2805 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static constexpr decltype(Func{}( |
2806 | | detail::left_closed_directed_t{}, Args{}...)) |
2807 | | delegate(SignedSignificandBits s, Func f, Args... args) noexcept |
2808 | | { |
2809 | | return s.is_negative() ? f(detail::right_closed_directed_t{}, args...) |
2810 | | : f(detail::left_closed_directed_t{}, args...); |
2811 | | } |
2812 | | } toward_minus_infinity = {}; |
2813 | | |
2814 | | GLZ_JKJ_INLINE_VARIABLE struct toward_zero_t |
2815 | | { |
2816 | | using decimal_to_binary_rounding_policy = toward_zero_t; |
2817 | | |
2818 | | template <class SignedSignificandBits, class Func, class... Args> |
2819 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static constexpr decltype(Func{}( |
2820 | | detail::left_closed_directed_t{}, Args{}...)) |
2821 | | delegate(SignedSignificandBits, Func f, Args... args) noexcept |
2822 | | { |
2823 | | return f(detail::left_closed_directed_t{}, args...); |
2824 | | } |
2825 | | } toward_zero = {}; |
2826 | | |
2827 | | GLZ_JKJ_INLINE_VARIABLE struct away_from_zero_t |
2828 | | { |
2829 | | using decimal_to_binary_rounding_policy = away_from_zero_t; |
2830 | | |
2831 | | template <class SignedSignificandBits, class Func, class... Args> |
2832 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static constexpr decltype(Func{}( |
2833 | | detail::right_closed_directed_t{}, Args{}...)) |
2834 | | delegate(SignedSignificandBits, Func f, Args... args) noexcept |
2835 | | { |
2836 | | return f(detail::right_closed_directed_t{}, args...); |
2837 | | } |
2838 | | } away_from_zero = {}; |
2839 | | } |
2840 | | |
2841 | | namespace binary_to_decimal_rounding |
2842 | | { |
2843 | | // (Always assumes nearest rounding modes, as there can be no tie for other rounding |
2844 | | // modes.) |
2845 | | enum class tag_t { do_not_care, to_even, to_odd, away_from_zero, toward_zero }; |
2846 | | |
2847 | | // The parameter significand corresponds to 10\tilde{s}+t in the paper. |
2848 | | |
2849 | | GLZ_JKJ_INLINE_VARIABLE struct do_not_care_t |
2850 | | { |
2851 | | using binary_to_decimal_rounding_policy = do_not_care_t; |
2852 | | static constexpr auto tag = tag_t::do_not_care; |
2853 | | |
2854 | | template <class CarrierUInt> |
2855 | | static constexpr bool prefer_round_down(CarrierUInt) noexcept |
2856 | | { |
2857 | | return false; |
2858 | | } |
2859 | | } do_not_care = {}; |
2860 | | |
2861 | | GLZ_JKJ_INLINE_VARIABLE struct to_even_t |
2862 | | { |
2863 | | using binary_to_decimal_rounding_policy = to_even_t; |
2864 | | static constexpr auto tag = tag_t::to_even; |
2865 | | |
2866 | | template <class CarrierUInt> |
2867 | | static constexpr bool prefer_round_down(CarrierUInt significand) noexcept |
2868 | 0 | { |
2869 | 0 | return significand % 2 != 0; |
2870 | 0 | } Unexecuted instantiation: bool glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t::prefer_round_down<unsigned long>(unsigned long) Unexecuted instantiation: bool glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t::prefer_round_down<unsigned int>(unsigned int) |
2871 | | } to_even = {}; |
2872 | | |
2873 | | GLZ_JKJ_INLINE_VARIABLE struct to_odd_t |
2874 | | { |
2875 | | using binary_to_decimal_rounding_policy = to_odd_t; |
2876 | | static constexpr auto tag = tag_t::to_odd; |
2877 | | |
2878 | | template <class CarrierUInt> |
2879 | | static constexpr bool prefer_round_down(CarrierUInt significand) noexcept |
2880 | | { |
2881 | | return significand % 2 == 0; |
2882 | | } |
2883 | | } to_odd = {}; |
2884 | | |
2885 | | GLZ_JKJ_INLINE_VARIABLE struct away_from_zero_t |
2886 | | { |
2887 | | using binary_to_decimal_rounding_policy = away_from_zero_t; |
2888 | | static constexpr auto tag = tag_t::away_from_zero; |
2889 | | |
2890 | | template <class CarrierUInt> |
2891 | | static constexpr bool prefer_round_down(CarrierUInt) noexcept |
2892 | | { |
2893 | | return false; |
2894 | | } |
2895 | | } away_from_zero = {}; |
2896 | | |
2897 | | GLZ_JKJ_INLINE_VARIABLE struct toward_zero_t |
2898 | | { |
2899 | | using binary_to_decimal_rounding_policy = toward_zero_t; |
2900 | | static constexpr auto tag = tag_t::toward_zero; |
2901 | | |
2902 | | template <class CarrierUInt> |
2903 | | static constexpr bool prefer_round_down(CarrierUInt) noexcept |
2904 | | { |
2905 | | return true; |
2906 | | } |
2907 | | } toward_zero = {}; |
2908 | | } |
2909 | | |
2910 | | namespace cache |
2911 | | { |
2912 | | GLZ_JKJ_INLINE_VARIABLE struct full_t |
2913 | | { |
2914 | | using cache_policy = full_t; |
2915 | | template <class FloatFormat> |
2916 | | using cache_holder_type = cache_holder<FloatFormat>; |
2917 | | |
2918 | | template <class FloatFormat, class ShiftAmountType, class DecimalExponentType> |
2919 | | static constexpr typename cache_holder_type<FloatFormat>::cache_entry_type get_cache( |
2920 | | DecimalExponentType k) noexcept |
2921 | 0 | { |
2922 | 0 | #if GLZ_JKJ_HAS_CONSTEXPR14 |
2923 | 0 | assert(k >= cache_holder_type<FloatFormat>::min_k && k <= cache_holder_type<FloatFormat>::max_k); |
2924 | 0 | #endif |
2925 | 0 | return cache_holder_type<FloatFormat>::cache[detail::stdr::size_t( |
2926 | 0 | k - cache_holder_type<FloatFormat>::min_k)]; |
2927 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::cache_holder<glz::jkj::dragonbox::ieee754_binary64, void>::cache_entry_type glz::jkj::dragonbox::policy::cache::full_t::get_cache<glz::jkj::dragonbox::ieee754_binary64, int, int>(int) Unexecuted instantiation: glz::jkj::dragonbox::cache_holder<glz::jkj::dragonbox::ieee754_binary32, void>::cache_entry_type glz::jkj::dragonbox::policy::cache::full_t::get_cache<glz::jkj::dragonbox::ieee754_binary32, int, int>(int) |
2928 | | } full = {}; |
2929 | | |
2930 | | GLZ_JKJ_INLINE_VARIABLE struct compact_t |
2931 | | { |
2932 | | using cache_policy = compact_t; |
2933 | | template <class FloatFormat> |
2934 | | using cache_holder_type = compressed_cache_holder<FloatFormat>; |
2935 | | |
2936 | | template <class FloatFormat, class ShiftAmountType, class DecimalExponentType> |
2937 | | static GLZ_JKJ_CONSTEXPR20 typename cache_holder<FloatFormat>::cache_entry_type get_cache( |
2938 | | DecimalExponentType k) noexcept |
2939 | | { |
2940 | | assert(k >= cache_holder<FloatFormat>::min_k && k <= cache_holder<FloatFormat>::max_k); |
2941 | | |
2942 | | return cache_holder_type<FloatFormat>::template get_cache<ShiftAmountType>(k); |
2943 | | } |
2944 | | } compact = {}; |
2945 | | } |
2946 | | |
2947 | | namespace preferred_integer_types |
2948 | | { |
2949 | | GLZ_JKJ_INLINE_VARIABLE struct match_t |
2950 | | { |
2951 | | using preferred_integer_types_policy = match_t; |
2952 | | |
2953 | | template <class FormatTraits, detail::stdr::uint_least64_t upper_bound> |
2954 | | using remainder_type = typename FormatTraits::carrier_uint; |
2955 | | |
2956 | | template <class FormatTraits, detail::stdr::int_least32_t lower_bound, |
2957 | | detail::stdr::uint_least32_t upper_bound> |
2958 | | using decimal_exponent_type = typename FormatTraits::exponent_int; |
2959 | | |
2960 | | template <class FormatTraits> |
2961 | | using shift_amount_type = typename FormatTraits::exponent_int; |
2962 | | } match; |
2963 | | |
2964 | | GLZ_JKJ_INLINE_VARIABLE struct prefer_32_t |
2965 | | { |
2966 | | using preferred_integer_types_policy = prefer_32_t; |
2967 | | |
2968 | | template <class FormatTraits, detail::stdr::uint_least64_t upper_bound> |
2969 | | using remainder_type = typename detail::stdr::conditional< |
2970 | | upper_bound <= (detail::stdr::numeric_limits<detail::stdr::uint_least32_t>::max)(), |
2971 | | detail::stdr::uint_least32_t, typename FormatTraits::carrier_uint>::type; |
2972 | | |
2973 | | template <class FormatTraits, detail::stdr::int_least32_t lower_bound, |
2974 | | detail::stdr::uint_least32_t upper_bound> |
2975 | | using decimal_exponent_type = typename detail::stdr::conditional< |
2976 | | FormatTraits::format::exponent_bits <= detail::value_bits<detail::stdr::int_least32_t>::value, |
2977 | | detail::stdr::int_least32_t, typename FormatTraits::exponent_int>::type; |
2978 | | |
2979 | | template <class FormatTraits> |
2980 | | using shift_amount_type = detail::stdr::int_least32_t; |
2981 | | } prefer_32; |
2982 | | |
2983 | | GLZ_JKJ_INLINE_VARIABLE struct minimal_t |
2984 | | { |
2985 | | using preferred_integer_types_policy = minimal_t; |
2986 | | |
2987 | | template <class FormatTraits, detail::stdr::uint_least64_t upper_bound> |
2988 | | using remainder_type = typename detail::stdr::conditional< |
2989 | | upper_bound <= (detail::stdr::numeric_limits<detail::stdr::uint_least8_t>::max)(), |
2990 | | detail::stdr::uint_least8_t, |
2991 | | typename detail::stdr::conditional< |
2992 | | upper_bound <= (detail::stdr::numeric_limits<detail::stdr::uint_least16_t>::max)(), |
2993 | | detail::stdr::uint_least16_t, |
2994 | | typename detail::stdr::conditional< |
2995 | | upper_bound <= (detail::stdr::numeric_limits<detail::stdr::uint_least32_t>::max)(), |
2996 | | detail::stdr::uint_least32_t, |
2997 | | typename detail::stdr::conditional< |
2998 | | upper_bound <= (detail::stdr::numeric_limits<detail::stdr::uint_least64_t>::max)(), |
2999 | | detail::stdr::uint_least64_t, typename FormatTraits::carrier_uint>::type>::type>::type>:: |
3000 | | type; |
3001 | | |
3002 | | template <class FormatTraits, detail::stdr::int_least32_t lower_bound, |
3003 | | detail::stdr::uint_least32_t upper_bound> |
3004 | | using decimal_exponent_type = typename detail::stdr::conditional< |
3005 | | lower_bound >= (detail::stdr::numeric_limits<detail::stdr::int_least8_t>::min)() && |
3006 | | upper_bound <= (detail::stdr::numeric_limits<detail::stdr::int_least8_t>::max)(), |
3007 | | detail::stdr::int_least8_t, |
3008 | | typename detail::stdr::conditional< |
3009 | | lower_bound >= (detail::stdr::numeric_limits<detail::stdr::int_least16_t>::min)() && |
3010 | | upper_bound <= (detail::stdr::numeric_limits<detail::stdr::int_least16_t>::max)(), |
3011 | | detail::stdr::int_least16_t, |
3012 | | typename detail::stdr::conditional< |
3013 | | lower_bound >= (detail::stdr::numeric_limits<detail::stdr::int_least32_t>::min)() && |
3014 | | upper_bound <= (detail::stdr::numeric_limits<detail::stdr::int_least32_t>::max)(), |
3015 | | detail::stdr::int_least32_t, typename FormatTraits::exponent_int>::type>::type>::type; |
3016 | | |
3017 | | template <class FormatTraits> |
3018 | | using shift_amount_type = detail::stdr::int_least8_t; |
3019 | | } minimal; |
3020 | | } |
3021 | | } |
3022 | | |
3023 | | //////////////////////////////////////////////////////////////////////////////////////// |
3024 | | // Specializations of user-specializable templates used in the main algorithm. |
3025 | | //////////////////////////////////////////////////////////////////////////////////////// |
3026 | | |
3027 | | template <class DecimalExponentType> |
3028 | | struct remove_trailing_zeros_traits<policy::trailing_zero::remove_t, ieee754_binary32, |
3029 | | detail::stdr::uint_least32_t, DecimalExponentType> |
3030 | | { |
3031 | | GLZ_JKJ_FORCEINLINE static GLZ_JKJ_CONSTEXPR14 void remove_trailing_zeros( |
3032 | | detail::stdr::uint_least32_t& significand, DecimalExponentType& exponent) noexcept |
3033 | 0 | { |
3034 | 0 | // See https://github.com/jk-jeon/rtz_benchmark. |
3035 | 0 | // The idea of branchless search below is by reddit users r/pigeon768 and |
3036 | 0 | // r/TheoreticalDumbass. |
3037 | 0 |
|
3038 | 0 | auto r = detail::bits::rotr<32>(detail::stdr::uint_least32_t(significand * UINT32_C(184254097)), 4); |
3039 | 0 | auto b = r < UINT32_C(429497); |
3040 | 0 | auto s = detail::stdr::size_t(b); |
3041 | 0 | significand = b ? r : significand; |
3042 | 0 |
|
3043 | 0 | r = detail::bits::rotr<32>(detail::stdr::uint_least32_t(significand * UINT32_C(42949673)), 2); |
3044 | 0 | b = r < UINT32_C(42949673); |
3045 | 0 | s = s * 2 + b; |
3046 | 0 | significand = b ? r : significand; |
3047 | 0 |
|
3048 | 0 | r = detail::bits::rotr<32>(detail::stdr::uint_least32_t(significand * UINT32_C(1288490189)), 1); |
3049 | 0 | b = r < UINT32_C(429496730); |
3050 | 0 | s = s * 2 + b; |
3051 | 0 | significand = b ? r : significand; |
3052 | 0 |
|
3053 | 0 | exponent += s; |
3054 | 0 | } |
3055 | | }; |
3056 | | |
3057 | | template <class DecimalExponentType> |
3058 | | struct remove_trailing_zeros_traits<policy::trailing_zero::remove_t, ieee754_binary64, |
3059 | | detail::stdr::uint_least64_t, DecimalExponentType> |
3060 | | { |
3061 | | GLZ_JKJ_FORCEINLINE static GLZ_JKJ_CONSTEXPR14 void remove_trailing_zeros( |
3062 | | detail::stdr::uint_least64_t& significand, DecimalExponentType& exponent) noexcept |
3063 | | { |
3064 | | // See https://github.com/jk-jeon/rtz_benchmark. |
3065 | | // The idea of branchless search below is by reddit users r/pigeon768 and |
3066 | | // r/TheoreticalDumbass. |
3067 | | |
3068 | | auto r = detail::bits::rotr<64>(detail::stdr::uint_least64_t(significand * UINT64_C(28999941890838049)), 8); |
3069 | | auto b = r < UINT64_C(184467440738); |
3070 | | auto s = detail::stdr::size_t(b); |
3071 | | significand = b ? r : significand; |
3072 | | |
3073 | | r = detail::bits::rotr<64>(detail::stdr::uint_least64_t(significand * UINT64_C(182622766329724561)), 4); |
3074 | | b = r < UINT64_C(1844674407370956); |
3075 | | s = s * 2 + b; |
3076 | | significand = b ? r : significand; |
3077 | | |
3078 | | r = detail::bits::rotr<64>(detail::stdr::uint_least64_t(significand * UINT64_C(10330176681277348905)), 2); |
3079 | | b = r < UINT64_C(184467440737095517); |
3080 | | s = s * 2 + b; |
3081 | | significand = b ? r : significand; |
3082 | | |
3083 | | r = detail::bits::rotr<64>(detail::stdr::uint_least64_t(significand * UINT32_C(14757395258967641293)), 1); |
3084 | | b = r < UINT64_C(1844674407370955162); |
3085 | | s = s * 2 + b; |
3086 | | significand = b ? r : significand; |
3087 | | |
3088 | | exponent += s; |
3089 | | } |
3090 | | }; |
3091 | | |
3092 | | template <class DecimalExponentType> |
3093 | | struct remove_trailing_zeros_traits<policy::trailing_zero::remove_compact_t, ieee754_binary32, |
3094 | | detail::stdr::uint_least32_t, DecimalExponentType> |
3095 | | { |
3096 | | GLZ_JKJ_FORCEINLINE static GLZ_JKJ_CONSTEXPR14 void remove_trailing_zeros( |
3097 | | detail::stdr::uint_least32_t& significand, DecimalExponentType& exponent) noexcept |
3098 | | { |
3099 | | // See https://github.com/jk-jeon/rtz_benchmark. |
3100 | | while (true) { |
3101 | | const auto r = detail::stdr::uint_least32_t(significand * UINT32_C(1288490189)); |
3102 | | if (r < UINT32_C(429496731)) { |
3103 | | significand = detail::stdr::uint_least32_t(r >> 1); |
3104 | | exponent += 1; |
3105 | | } |
3106 | | else { |
3107 | | break; |
3108 | | } |
3109 | | } |
3110 | | } |
3111 | | }; |
3112 | | |
3113 | | template <class DecimalExponentType> |
3114 | | struct remove_trailing_zeros_traits<policy::trailing_zero::remove_compact_t, ieee754_binary64, |
3115 | | detail::stdr::uint_least64_t, DecimalExponentType> |
3116 | | { |
3117 | | GLZ_JKJ_FORCEINLINE static GLZ_JKJ_CONSTEXPR14 void remove_trailing_zeros( |
3118 | | detail::stdr::uint_least64_t& significand, DecimalExponentType& exponent) noexcept |
3119 | | { |
3120 | | // See https://github.com/jk-jeon/rtz_benchmark. |
3121 | | while (true) { |
3122 | | const auto r = detail::stdr::uint_least64_t(significand * UINT64_C(5534023222112865485)); |
3123 | | if (r < UINT64_C(1844674407370955163)) { |
3124 | | significand = detail::stdr::uint_least64_t(r >> 1); |
3125 | | exponent += 1; |
3126 | | } |
3127 | | else { |
3128 | | break; |
3129 | | } |
3130 | | } |
3131 | | } |
3132 | | }; |
3133 | | |
3134 | | template <class ExponentInt> |
3135 | | struct multiplication_traits<ieee754_binary_traits<ieee754_binary32, detail::stdr::uint_least32_t, ExponentInt>, |
3136 | | detail::stdr::uint_least64_t, 64> |
3137 | | : public multiplication_traits_base<ieee754_binary_traits<ieee754_binary32, detail::stdr::uint_least32_t>, |
3138 | | detail::stdr::uint_least64_t, 64> |
3139 | | { |
3140 | | static GLZ_JKJ_CONSTEXPR20 compute_mul_result compute_mul(carrier_uint u, |
3141 | | const cache_entry_type& cache) noexcept |
3142 | 0 | { |
3143 | 0 | const auto r = detail::wuint::umul96_upper64(u, cache); |
3144 | 0 | return {carrier_uint(r >> 32), carrier_uint(r) == 0}; |
3145 | 0 | } |
3146 | | |
3147 | | template <class ShiftAmountType> |
3148 | | static constexpr detail::stdr::uint_least64_t compute_delta(const cache_entry_type& cache, |
3149 | | ShiftAmountType beta) noexcept |
3150 | 0 | { |
3151 | 0 | return detail::stdr::uint_least64_t(cache >> ShiftAmountType(cache_bits - 1 - beta)); |
3152 | 0 | } |
3153 | | |
3154 | | template <class ShiftAmountType> |
3155 | | static GLZ_JKJ_CONSTEXPR20 compute_mul_parity_result compute_mul_parity(carrier_uint two_f, |
3156 | | const cache_entry_type& cache, |
3157 | | ShiftAmountType beta) noexcept |
3158 | 0 | { |
3159 | 0 | assert(beta >= 1); |
3160 | 0 | assert(beta <= 32); |
3161 | 0 |
|
3162 | 0 | const auto r = detail::wuint::umul96_lower64(two_f, cache); |
3163 | 0 | return {((r >> ShiftAmountType(64 - beta)) & 1) != 0, |
3164 | 0 | (UINT32_C(0xffffffff) & (r >> ShiftAmountType(32 - beta))) == 0}; |
3165 | 0 | } |
3166 | | |
3167 | | template <class ShiftAmountType> |
3168 | | static constexpr carrier_uint compute_left_endpoint_for_shorter_interval_case(const cache_entry_type& cache, |
3169 | | ShiftAmountType beta) noexcept |
3170 | 0 | { |
3171 | 0 | return carrier_uint((cache - (cache >> (significand_bits + 2))) >> |
3172 | 0 | ShiftAmountType(cache_bits - significand_bits - 1 - beta)); |
3173 | 0 | } |
3174 | | |
3175 | | template <class ShiftAmountType> |
3176 | | static constexpr carrier_uint compute_right_endpoint_for_shorter_interval_case(const cache_entry_type& cache, |
3177 | | ShiftAmountType beta) noexcept |
3178 | 0 | { |
3179 | 0 | return carrier_uint((cache + (cache >> (significand_bits + 1))) >> |
3180 | 0 | ShiftAmountType(cache_bits - significand_bits - 1 - beta)); |
3181 | 0 | } |
3182 | | |
3183 | | template <class ShiftAmountType> |
3184 | | static constexpr carrier_uint compute_round_up_for_shorter_interval_case(const cache_entry_type& cache, |
3185 | | ShiftAmountType beta) noexcept |
3186 | 0 | { |
3187 | 0 | return (carrier_uint(cache >> ShiftAmountType(cache_bits - significand_bits - 2 - beta)) + 1) / 2; |
3188 | 0 | } |
3189 | | }; |
3190 | | |
3191 | | template <class ExponentInt> |
3192 | | struct multiplication_traits<ieee754_binary_traits<ieee754_binary64, detail::stdr::uint_least64_t, ExponentInt>, |
3193 | | detail::wuint::uint128, 128> |
3194 | | : public multiplication_traits_base<ieee754_binary_traits<ieee754_binary64, detail::stdr::uint_least64_t>, |
3195 | | detail::wuint::uint128, 128> |
3196 | | { |
3197 | | static GLZ_JKJ_CONSTEXPR20 compute_mul_result compute_mul(carrier_uint u, |
3198 | | const cache_entry_type& cache) noexcept |
3199 | 0 | { |
3200 | 0 | const auto r = detail::wuint::umul192_upper128(u, cache); |
3201 | 0 | return {r.high(), r.low() == 0}; |
3202 | 0 | } |
3203 | | |
3204 | | template <class ShiftAmountType> |
3205 | | static constexpr detail::stdr::uint_least64_t compute_delta(const cache_entry_type& cache, |
3206 | | ShiftAmountType beta) noexcept |
3207 | 0 | { |
3208 | 0 | return detail::stdr::uint_least64_t(cache.high() >> ShiftAmountType(total_bits - 1 - beta)); |
3209 | 0 | } |
3210 | | |
3211 | | template <class ShiftAmountType> |
3212 | | static GLZ_JKJ_CONSTEXPR20 compute_mul_parity_result compute_mul_parity(carrier_uint two_f, |
3213 | | const cache_entry_type& cache, |
3214 | | ShiftAmountType beta) noexcept |
3215 | 0 | { |
3216 | 0 | assert(beta >= 1); |
3217 | 0 | assert(beta < 64); |
3218 | 0 |
|
3219 | 0 | const auto r = detail::wuint::umul192_lower128(two_f, cache); |
3220 | 0 | return { |
3221 | 0 | ((r.high() >> ShiftAmountType(64 - beta)) & 1) != 0, |
3222 | 0 | (((r.high() << beta) & UINT64_C(0xffffffffffffffff)) | (r.low() >> ShiftAmountType(64 - beta))) == 0}; |
3223 | 0 | } |
3224 | | |
3225 | | template <class ShiftAmountType> |
3226 | | static constexpr carrier_uint compute_left_endpoint_for_shorter_interval_case(const cache_entry_type& cache, |
3227 | | ShiftAmountType beta) noexcept |
3228 | 0 | { |
3229 | 0 | return (cache.high() - (cache.high() >> (significand_bits + 2))) >> |
3230 | 0 | ShiftAmountType(total_bits - significand_bits - 1 - beta); |
3231 | 0 | } |
3232 | | |
3233 | | template <class ShiftAmountType> |
3234 | | static constexpr carrier_uint compute_right_endpoint_for_shorter_interval_case(const cache_entry_type& cache, |
3235 | | ShiftAmountType beta) noexcept |
3236 | 0 | { |
3237 | 0 | return (cache.high() + (cache.high() >> (significand_bits + 1))) >> |
3238 | 0 | ShiftAmountType(total_bits - significand_bits - 1 - beta); |
3239 | 0 | } |
3240 | | |
3241 | | template <class ShiftAmountType> |
3242 | | static constexpr carrier_uint compute_round_up_for_shorter_interval_case(const cache_entry_type& cache, |
3243 | | ShiftAmountType beta) noexcept |
3244 | 0 | { |
3245 | 0 | return ((cache.high() >> ShiftAmountType(total_bits - significand_bits - 2 - beta)) + 1) / 2; |
3246 | 0 | } |
3247 | | }; |
3248 | | |
3249 | | namespace detail |
3250 | | { |
3251 | | //////////////////////////////////////////////////////////////////////////////////////// |
3252 | | // The main algorithm. |
3253 | | //////////////////////////////////////////////////////////////////////////////////////// |
3254 | | |
3255 | | template <class FormatTraits> |
3256 | | struct impl : private FormatTraits::format |
3257 | | { |
3258 | | using format = typename FormatTraits::format; |
3259 | | using carrier_uint = typename FormatTraits::carrier_uint; |
3260 | | static constexpr int carrier_bits = FormatTraits::carrier_bits; |
3261 | | using exponent_int = typename FormatTraits::exponent_int; |
3262 | | |
3263 | | using format::exponent_bias; |
3264 | | using format::max_exponent; |
3265 | | using format::min_exponent; |
3266 | | using format::significand_bits; |
3267 | | |
3268 | | static constexpr int kappa = log::floor_log10_pow2(carrier_bits - significand_bits - 2) - 1; |
3269 | | static_assert(kappa >= 1, ""); |
3270 | | static_assert(carrier_bits >= significand_bits + 2 + log::floor_log2_pow10(kappa + 1), ""); |
3271 | | #undef min |
3272 | | #undef max |
3273 | 0 | static constexpr int min(int x, int y) noexcept { return x < y ? x : y; } Unexecuted instantiation: glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::min(int, int) Unexecuted instantiation: glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::min(int, int) |
3274 | 0 | static constexpr int max(int x, int y) noexcept { return x > y ? x : y; } Unexecuted instantiation: glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::max(int, int) Unexecuted instantiation: glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::max(int, int) |
3275 | | |
3276 | | static constexpr int min_k = |
3277 | | min(-log::floor_log10_pow2_minus_log10_4_over_3(max_exponent - significand_bits), |
3278 | | -log::floor_log10_pow2(max_exponent - significand_bits) + kappa); |
3279 | | |
3280 | | // We do invoke shorter_interval_case for exponent == min_exponent case, |
3281 | | // so we should not add 1 here. |
3282 | | static constexpr int max_k = |
3283 | | max(-log::floor_log10_pow2_minus_log10_4_over_3(min_exponent - significand_bits /*+ 1*/), |
3284 | | -log::floor_log10_pow2(min_exponent - significand_bits) + kappa); |
3285 | | |
3286 | | static constexpr int case_shorter_interval_left_endpoint_lower_threshold = 2; |
3287 | | static constexpr int case_shorter_interval_left_endpoint_upper_threshold = |
3288 | | 2 + log::floor_log2( |
3289 | | compute_power<count_factors<5>((carrier_uint(1) << (significand_bits + 2)) - 1) + 1>(10) / 3); |
3290 | | |
3291 | | static constexpr int case_shorter_interval_right_endpoint_lower_threshold = 0; |
3292 | | static constexpr int case_shorter_interval_right_endpoint_upper_threshold = |
3293 | | 2 + log::floor_log2( |
3294 | | compute_power<count_factors<5>((carrier_uint(1) << (significand_bits + 1)) + 1) + 1>(10) / 3); |
3295 | | |
3296 | | static constexpr int shorter_interval_tie_lower_threshold = |
3297 | | -log::floor_log5_pow2_minus_log5_3(significand_bits + 4) - 2 - significand_bits; |
3298 | | static constexpr int shorter_interval_tie_upper_threshold = |
3299 | | -log::floor_log5_pow2(significand_bits + 2) - 2 - significand_bits; |
3300 | | |
3301 | | template <class PreferredIntegerTypesPolicy> |
3302 | | using remainder_type = typename PreferredIntegerTypesPolicy::template remainder_type< |
3303 | | FormatTraits, compute_power<kappa + 1>(detail::stdr::uint_least64_t(10))>; |
3304 | | |
3305 | | template <class PreferredIntegerTypesPolicy> |
3306 | | using decimal_exponent_type = typename PreferredIntegerTypesPolicy::template decimal_exponent_type< |
3307 | | FormatTraits, detail::stdr::int_least32_t(min(-max_k, min_k)), |
3308 | | detail::stdr::int_least32_t(max(max_k, -min_k + kappa + 1))>; |
3309 | | |
3310 | | template <class SignPolicy, class TrailingZeroPolicy, class PreferredIntegerTypesPolicy> |
3311 | | using return_type = decimal_fp<carrier_uint, decimal_exponent_type<PreferredIntegerTypesPolicy>, |
3312 | | SignPolicy::return_has_sign, TrailingZeroPolicy::report_trailing_zeros>; |
3313 | | |
3314 | | //// The main algorithm assumes the input is a normal/subnormal finite number. |
3315 | | |
3316 | | template <class SignPolicy, class TrailingZeroPolicy, class IntervalTypeProvider, |
3317 | | class BinaryToDecimalRoundingPolicy, class CachePolicy, class PreferredIntegerTypesPolicy> |
3318 | | GLZ_JKJ_SAFEBUFFERS static GLZ_JKJ_CONSTEXPR20 |
3319 | | return_type<SignPolicy, TrailingZeroPolicy, PreferredIntegerTypesPolicy> |
3320 | | compute_nearest(signed_significand_bits<FormatTraits> s, exponent_int exponent_bits) noexcept |
3321 | 0 | { |
3322 | 0 | using cache_holder_type = typename CachePolicy::template cache_holder_type<format>; |
3323 | 0 | static_assert(min_k >= cache_holder_type::min_k && max_k <= cache_holder_type::max_k, ""); |
3324 | 0 |
|
3325 | 0 | using remainder_type_ = remainder_type<PreferredIntegerTypesPolicy>; |
3326 | 0 | using decimal_exponent_type_ = decimal_exponent_type<PreferredIntegerTypesPolicy>; |
3327 | 0 | using shift_amount_type = typename PreferredIntegerTypesPolicy::template shift_amount_type<FormatTraits>; |
3328 | 0 |
|
3329 | 0 | using multiplication_traits_ = |
3330 | 0 | multiplication_traits<FormatTraits, typename cache_holder_type::cache_entry_type, |
3331 | 0 | cache_holder_type::cache_bits>; |
3332 | 0 |
|
3333 | 0 | auto two_fc = s.remove_sign_bit_and_shift(); |
3334 | 0 | auto binary_exponent = exponent_bits; |
3335 | 0 |
|
3336 | 0 | // Is the input a normal number? |
3337 | 0 | if (binary_exponent != 0) { |
3338 | 0 | binary_exponent += format::exponent_bias - format::significand_bits; |
3339 | 0 |
|
3340 | 0 | // Shorter interval case; proceed like Schubfach. |
3341 | 0 | // One might think this condition is wrong, since when exponent_bits == |
3342 | 0 | // 1 and two_fc == 0, the interval is actually regular. However, it |
3343 | 0 | // turns out that this seemingly wrong condition is actually fine, |
3344 | 0 | // because the end result is anyway the same. |
3345 | 0 | // |
3346 | 0 | // [binary32] |
3347 | 0 | // (fc-1/2) * 2^e = 1.175'494'28... * 10^-38 |
3348 | 0 | // (fc-1/4) * 2^e = 1.175'494'31... * 10^-38 |
3349 | 0 | // fc * 2^e = 1.175'494'35... * 10^-38 |
3350 | 0 | // (fc+1/2) * 2^e = 1.175'494'42... * 10^-38 |
3351 | 0 | // |
3352 | 0 | // Hence, shorter_interval_case will return 1.175'494'4 * 10^-38. |
3353 | 0 | // 1.175'494'3 * 10^-38 is also a correct shortest representation that |
3354 | 0 | // will be rejected if we assume shorter interval, but 1.175'494'4 * |
3355 | 0 | // 10^-38 is closer to the true value so it doesn't matter. |
3356 | 0 | // |
3357 | 0 | // [binary64] |
3358 | 0 | // (fc-1/2) * 2^e = 2.225'073'858'507'201'13... * 10^-308 |
3359 | 0 | // (fc-1/4) * 2^e = 2.225'073'858'507'201'25... * 10^-308 |
3360 | 0 | // fc * 2^e = 2.225'073'858'507'201'38... * 10^-308 |
3361 | 0 | // (fc+1/2) * 2^e = 2.225'073'858'507'201'63... * 10^-308 |
3362 | 0 | // |
3363 | 0 | // Hence, shorter_interval_case will return 2.225'073'858'507'201'4 * |
3364 | 0 | // 10^-308. This is indeed of the shortest length, and it is the unique |
3365 | 0 | // one closest to the true value among valid representations of the same |
3366 | 0 | // length. |
3367 | 0 | static_assert( |
3368 | 0 | stdr::is_same<format, ieee754_binary32>::value || stdr::is_same<format, ieee754_binary64>::value, |
3369 | 0 | ""); |
3370 | 0 |
|
3371 | 0 | // Shorter interval case. |
3372 | 0 | if (two_fc == 0) { |
3373 | 0 | auto interval_type = IntervalTypeProvider::shorter_interval(s); |
3374 | 0 |
|
3375 | 0 | // Compute k and beta. |
3376 | 0 | const auto minus_k = |
3377 | 0 | log::floor_log10_pow2_minus_log10_4_over_3<min_exponent - format::significand_bits, |
3378 | 0 | max_exponent - format::significand_bits, |
3379 | 0 | decimal_exponent_type_>(binary_exponent); |
3380 | 0 | const auto beta = shift_amount_type( |
3381 | 0 | binary_exponent + log::floor_log2_pow10<min_k, max_k>(decimal_exponent_type_(-minus_k))); |
3382 | 0 |
|
3383 | 0 | // Compute xi and zi. |
3384 | 0 | const auto cache = |
3385 | 0 | CachePolicy::template get_cache<format, shift_amount_type>(decimal_exponent_type_(-minus_k)); |
3386 | 0 |
|
3387 | 0 | auto xi = multiplication_traits_::compute_left_endpoint_for_shorter_interval_case(cache, beta); |
3388 | 0 | auto zi = multiplication_traits_::compute_right_endpoint_for_shorter_interval_case(cache, beta); |
3389 | 0 |
|
3390 | 0 | // If we don't accept the right endpoint and |
3391 | 0 | // if the right endpoint is an integer, decrease it. |
3392 | 0 | if (!interval_type.include_right_endpoint() && |
3393 | 0 | is_right_endpoint_integer_shorter_interval(binary_exponent)) { |
3394 | 0 | --zi; |
3395 | 0 | } |
3396 | 0 | // If we don't accept the left endpoint or |
3397 | 0 | // if the left endpoint is not an integer, increase it. |
3398 | 0 | if (!interval_type.include_left_endpoint() || |
3399 | 0 | !is_left_endpoint_integer_shorter_interval(binary_exponent)) { |
3400 | 0 | ++xi; |
3401 | 0 | } |
3402 | 0 |
|
3403 | 0 | // Try bigger divisor. |
3404 | 0 | // zi is at most floor((f_c + 1/2) * 2^e * 10^k0). |
3405 | 0 | // Substituting f_c = 2^p and k0 = -floor(log10(3 * 2^(e-2))), we get |
3406 | 0 | // zi <= floor((2^(p+1) + 1) * 20/3) <= ceil((2^(p+1) + 1)/3) * 20. |
3407 | 0 | // This computation does not overflow for any of the formats I care about. |
3408 | 0 | carrier_uint decimal_significand = div::divide_by_pow10< |
3409 | 0 | 1, carrier_uint, |
3410 | 0 | carrier_uint(((((carrier_uint(1) << (significand_bits + 1)) + 1) / 3) + 1) * 20)>(zi); |
3411 | 0 |
|
3412 | 0 | // If succeed, remove trailing zeros if necessary and return. |
3413 | 0 | if (decimal_significand * 10 >= xi) { |
3414 | 0 | return SignPolicy::handle_sign(s, TrailingZeroPolicy::template on_trailing_zeros<format>( |
3415 | 0 | decimal_significand, decimal_exponent_type_(minus_k + 1))); |
3416 | 0 | } |
3417 | 0 |
|
3418 | 0 | // Otherwise, compute the round-up of y. |
3419 | 0 | decimal_significand = |
3420 | 0 | multiplication_traits_::compute_round_up_for_shorter_interval_case(cache, beta); |
3421 | 0 |
|
3422 | 0 | // When tie occurs, choose one of them according to the rule. |
3423 | 0 | if (BinaryToDecimalRoundingPolicy::prefer_round_down(decimal_significand) && |
3424 | 0 | binary_exponent >= shorter_interval_tie_lower_threshold && |
3425 | 0 | binary_exponent <= shorter_interval_tie_upper_threshold) { |
3426 | 0 | --decimal_significand; |
3427 | 0 | } |
3428 | 0 | else if (decimal_significand < xi) { |
3429 | 0 | ++decimal_significand; |
3430 | 0 | } |
3431 | 0 | return SignPolicy::handle_sign(s, TrailingZeroPolicy::template no_trailing_zeros<format>( |
3432 | 0 | decimal_significand, decimal_exponent_type_(minus_k))); |
3433 | 0 | } |
3434 | 0 |
|
3435 | 0 | // Normal interval case. |
3436 | 0 | two_fc |= (carrier_uint(1) << (format::significand_bits + 1)); |
3437 | 0 | } |
3438 | 0 | // Is the input a subnormal number? |
3439 | 0 | else { |
3440 | 0 | // Normal interval case. |
3441 | 0 | binary_exponent = format::min_exponent - format::significand_bits; |
3442 | 0 | } |
3443 | 0 |
|
3444 | 0 | ////////////////////////////////////////////////////////////////////// |
3445 | 0 | // Step 1: Schubfach multiplier calculation. |
3446 | 0 | ////////////////////////////////////////////////////////////////////// |
3447 | 0 |
|
3448 | 0 | auto interval_type = IntervalTypeProvider::normal_interval(s); |
3449 | 0 |
|
3450 | 0 | // Compute k and beta. |
3451 | 0 | const auto minus_k = decimal_exponent_type_( |
3452 | 0 | log::floor_log10_pow2<min_exponent - format::significand_bits, |
3453 | 0 | max_exponent - format::significand_bits, decimal_exponent_type_>( |
3454 | 0 | binary_exponent) - |
3455 | 0 | kappa); |
3456 | 0 | const auto cache = |
3457 | 0 | CachePolicy::template get_cache<format, shift_amount_type>(decimal_exponent_type_(-minus_k)); |
3458 | 0 | const auto beta = shift_amount_type( |
3459 | 0 | binary_exponent + log::floor_log2_pow10<min_k, max_k>(decimal_exponent_type_(-minus_k))); |
3460 | 0 |
|
3461 | 0 | // Compute zi and deltai. |
3462 | 0 | // 10^kappa <= deltai < 10^(kappa + 1) |
3463 | 0 | const auto deltai = static_cast<remainder_type_>(multiplication_traits_::compute_delta(cache, beta)); |
3464 | 0 | // For the case of binary32, the result of integer check is not correct for |
3465 | 0 | // 29711844 * 2^-82 |
3466 | 0 | // = 6.1442653300000000008655037797566933477355632930994033813476... * 10^-18 |
3467 | 0 | // and 29711844 * 2^-81 |
3468 | 0 | // = 1.2288530660000000001731007559513386695471126586198806762695... * 10^-17, |
3469 | 0 | // and they are the unique counterexamples. However, since 29711844 is even, |
3470 | 0 | // this does not cause any problem for the endpoints calculations; it can only |
3471 | 0 | // cause a problem when we need to perform integer check for the center. |
3472 | 0 | // Fortunately, with these inputs, that branch is never executed, so we are |
3473 | 0 | // fine. |
3474 | 0 | const auto z_result = multiplication_traits_::compute_mul(carrier_uint((two_fc | 1) << beta), cache); |
3475 | 0 |
|
3476 | 0 | ////////////////////////////////////////////////////////////////////// |
3477 | 0 | // Step 2: Try larger divisor; remove trailing zeros if necessary. |
3478 | 0 | ////////////////////////////////////////////////////////////////////// |
3479 | 0 |
|
3480 | 0 | constexpr auto big_divisor = compute_power<kappa + 1>(remainder_type_(10)); |
3481 | 0 | constexpr auto small_divisor = compute_power<kappa>(remainder_type_(10)); |
3482 | 0 |
|
3483 | 0 | // Using an upper bound on zi, we might be able to optimize the division |
3484 | 0 | // better than the compiler; we are computing zi / big_divisor here. |
3485 | 0 | carrier_uint decimal_significand = |
3486 | 0 | div::divide_by_pow10<kappa + 1, carrier_uint, |
3487 | 0 | carrier_uint((carrier_uint(1) << (significand_bits + 1)) * big_divisor - 1)>( |
3488 | 0 | z_result.integer_part); |
3489 | 0 | auto r = remainder_type_(z_result.integer_part - big_divisor * decimal_significand); |
3490 | 0 |
|
3491 | 0 | do { |
3492 | 0 | if (r < deltai) { |
3493 | 0 | // Exclude the right endpoint if necessary. |
3494 | 0 | if ((r | remainder_type_(!z_result.is_integer) | |
3495 | 0 | remainder_type_(interval_type.include_right_endpoint())) == 0) { |
3496 | 0 | GLZ_JKJ_IF_CONSTEXPR(BinaryToDecimalRoundingPolicy::tag == |
3497 | 0 | policy::binary_to_decimal_rounding::tag_t::do_not_care) |
3498 | 0 | { |
3499 | 0 | decimal_significand *= 10; |
3500 | 0 | --decimal_significand; |
3501 | 0 | return SignPolicy::handle_sign( |
3502 | 0 | s, TrailingZeroPolicy::template no_trailing_zeros<format>( |
3503 | 0 | decimal_significand, decimal_exponent_type_(minus_k + kappa))); |
3504 | 0 | } |
3505 | 0 | else |
3506 | 0 | { |
3507 | 0 | --decimal_significand; |
3508 | 0 | r = big_divisor; |
3509 | 0 | break; |
3510 | 0 | } |
3511 | 0 | } |
3512 | 0 | } |
3513 | 0 | else if (r > deltai) { |
3514 | 0 | break; |
3515 | 0 | } |
3516 | 0 | else { |
3517 | 0 | // r == deltai; compare fractional parts. |
3518 | 0 | const auto x_result = |
3519 | 0 | multiplication_traits_::compute_mul_parity(carrier_uint(two_fc - 1), cache, beta); |
3520 | 0 |
|
3521 | 0 | if (!(x_result.parity | (x_result.is_integer & interval_type.include_left_endpoint()))) { |
3522 | 0 | break; |
3523 | 0 | } |
3524 | 0 | } |
3525 | 0 |
|
3526 | 0 | // We may need to remove trailing zeros. |
3527 | 0 | return SignPolicy::handle_sign(s, |
3528 | 0 | TrailingZeroPolicy::template on_trailing_zeros<format>( |
3529 | 0 | decimal_significand, decimal_exponent_type_(minus_k + kappa + 1))); |
3530 | 0 | } while (false); |
3531 | 0 |
|
3532 | 0 | ////////////////////////////////////////////////////////////////////// |
3533 | 0 | // Step 3: Find the significand with the smaller divisor. |
3534 | 0 | ////////////////////////////////////////////////////////////////////// |
3535 | 0 |
|
3536 | 0 | decimal_significand *= 10; |
3537 | 0 |
|
3538 | 0 | GLZ_JKJ_IF_CONSTEXPR(BinaryToDecimalRoundingPolicy::tag == |
3539 | 0 | policy::binary_to_decimal_rounding::tag_t::do_not_care) |
3540 | 0 | { |
3541 | 0 | // Normally, we want to compute |
3542 | 0 | // significand += r / small_divisor |
3543 | 0 | // and return, but we need to take care of the case that the resulting |
3544 | 0 | // value is exactly the right endpoint, while that is not included in the |
3545 | 0 | // interval. |
3546 | 0 | if (!interval_type.include_right_endpoint()) { |
3547 | 0 | // Is r divisible by 10^kappa? |
3548 | 0 | if (div::check_divisibility_and_divide_by_pow10<kappa>(r) && z_result.is_integer) { |
3549 | 0 | // This should be in the interval. |
3550 | 0 | decimal_significand += r - 1; |
3551 | 0 | } |
3552 | 0 | else { |
3553 | 0 | decimal_significand += r; |
3554 | 0 | } |
3555 | 0 | } |
3556 | 0 | else { |
3557 | 0 | decimal_significand += div::small_division_by_pow10<kappa>(r); |
3558 | 0 | } |
3559 | 0 | } |
3560 | 0 | else |
3561 | 0 | { |
3562 | 0 | // delta is equal to 10^(kappa + elog10(2) - floor(elog10(2))), so dist cannot |
3563 | 0 | // be larger than r. |
3564 | 0 | auto dist = remainder_type_(r - (deltai / 2) + (small_divisor / 2)); |
3565 | 0 | const bool approx_y_parity = ((dist ^ (small_divisor / 2)) & 1) != 0; |
3566 | 0 |
|
3567 | 0 | // Is dist divisible by 10^kappa? |
3568 | 0 | const bool divisible_by_small_divisor = div::check_divisibility_and_divide_by_pow10<kappa>(dist); |
3569 | 0 |
|
3570 | 0 | // Add dist / 10^kappa to the significand. |
3571 | 0 | decimal_significand += dist; |
3572 | 0 |
|
3573 | 0 | if (divisible_by_small_divisor) { |
3574 | 0 | // Check z^(f) >= epsilon^(f). |
3575 | 0 | // We have either yi == zi - epsiloni or yi == (zi - epsiloni) - 1, |
3576 | 0 | // where yi == zi - epsiloni if and only if z^(f) >= epsilon^(f). |
3577 | 0 | // Since there are only 2 possibilities, we only need to care about the |
3578 | 0 | // parity. Also, zi and r should have the same parity since the divisor |
3579 | 0 | // is an even number. |
3580 | 0 | const auto y_result = multiplication_traits_::compute_mul_parity(two_fc, cache, beta); |
3581 | 0 | if (y_result.parity != approx_y_parity) { |
3582 | 0 | --decimal_significand; |
3583 | 0 | } |
3584 | 0 | else { |
3585 | 0 | // If z^(f) >= epsilon^(f), we might have a tie |
3586 | 0 | // when z^(f) == epsilon^(f), or equivalently, when y is an integer. |
3587 | 0 | // For tie-to-up case, we can just choose the upper one. |
3588 | 0 | if (BinaryToDecimalRoundingPolicy::prefer_round_down(decimal_significand) & |
3589 | 0 | y_result.is_integer) { |
3590 | 0 | --decimal_significand; |
3591 | 0 | } |
3592 | 0 | } |
3593 | 0 | } |
3594 | 0 | } |
3595 | 0 | return SignPolicy::handle_sign(s, TrailingZeroPolicy::template no_trailing_zeros<format>( |
3596 | 0 | decimal_significand, decimal_exponent_type_(minus_k + kappa))); |
3597 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::decimal_fp<unsigned long, glz::jkj::dragonbox::policy::preferred_integer_types::match_t::decimal_exponent_type<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int>, (int)(glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::min(-glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::max_k, glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::min_k)), (int)(glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::max(glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::max_k, ((-glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::min_k)+glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::kappa)+(1)))>, glz::jkj::dragonbox::policy::sign::ignore_t::return_has_sign, glz::jkj::dragonbox::policy::trailing_zero::ignore_t::report_trailing_zeros> glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::compute_nearest<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::ignore_t, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t, glz::jkj::dragonbox::policy::cache::full_t, glz::jkj::dragonbox::policy::preferred_integer_types::match_t>(glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >, int) Unexecuted instantiation: glz::jkj::dragonbox::decimal_fp<unsigned int, glz::jkj::dragonbox::policy::preferred_integer_types::match_t::decimal_exponent_type<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int>, (int)(glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::min(-glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::max_k, glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::min_k)), (int)(glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::max(glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::max_k, ((-glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::min_k)+glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::kappa)+(1)))>, glz::jkj::dragonbox::policy::sign::ignore_t::return_has_sign, glz::jkj::dragonbox::policy::trailing_zero::remove_t::report_trailing_zeros> glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::compute_nearest<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::remove_t, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t, glz::jkj::dragonbox::policy::cache::full_t, glz::jkj::dragonbox::policy::preferred_integer_types::match_t>(glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >, int) |
3598 | | |
3599 | | template <class SignPolicy, class TrailingZeroPolicy, class CachePolicy, class PreferredIntegerTypesPolicy> |
3600 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static GLZ_JKJ_CONSTEXPR20 |
3601 | | return_type<SignPolicy, TrailingZeroPolicy, PreferredIntegerTypesPolicy> |
3602 | | compute_left_closed_directed(signed_significand_bits<FormatTraits> s, |
3603 | | exponent_int exponent_bits) noexcept |
3604 | | { |
3605 | | using cache_holder_type = typename CachePolicy::template cache_holder_type<format>; |
3606 | | static_assert(min_k >= cache_holder_type::min_k && max_k <= cache_holder_type::max_k, ""); |
3607 | | |
3608 | | using remainder_type_ = remainder_type<PreferredIntegerTypesPolicy>; |
3609 | | using decimal_exponent_type_ = decimal_exponent_type<PreferredIntegerTypesPolicy>; |
3610 | | using shift_amount_type = typename PreferredIntegerTypesPolicy::template shift_amount_type<FormatTraits>; |
3611 | | |
3612 | | using multiplication_traits_ = |
3613 | | multiplication_traits<FormatTraits, typename cache_holder_type::cache_entry_type, |
3614 | | cache_holder_type::cache_bits>; |
3615 | | |
3616 | | auto two_fc = s.remove_sign_bit_and_shift(); |
3617 | | auto binary_exponent = exponent_bits; |
3618 | | |
3619 | | // Is the input a normal number? |
3620 | | if (binary_exponent != 0) { |
3621 | | binary_exponent += format::exponent_bias - format::significand_bits; |
3622 | | two_fc |= (carrier_uint(1) << (format::significand_bits + 1)); |
3623 | | } |
3624 | | // Is the input a subnormal number? |
3625 | | else { |
3626 | | binary_exponent = format::min_exponent - format::significand_bits; |
3627 | | } |
3628 | | |
3629 | | ////////////////////////////////////////////////////////////////////// |
3630 | | // Step 1: Schubfach multiplier calculation. |
3631 | | ////////////////////////////////////////////////////////////////////// |
3632 | | |
3633 | | // Compute k and beta. |
3634 | | const auto minus_k = decimal_exponent_type_( |
3635 | | log::floor_log10_pow2<format::min_exponent - format::significand_bits, |
3636 | | format::max_exponent - format::significand_bits, decimal_exponent_type_>( |
3637 | | binary_exponent) - |
3638 | | kappa); |
3639 | | const auto cache = |
3640 | | CachePolicy::template get_cache<format, shift_amount_type>(decimal_exponent_type_(-minus_k)); |
3641 | | const auto beta = shift_amount_type( |
3642 | | binary_exponent + log::floor_log2_pow10<min_k, max_k>(decimal_exponent_type_(-minus_k))); |
3643 | | |
3644 | | // Compute xi and deltai. |
3645 | | // 10^kappa <= deltai < 10^(kappa + 1) |
3646 | | const auto deltai = static_cast<remainder_type_>(multiplication_traits_::compute_delta(cache, beta)); |
3647 | | auto x_result = multiplication_traits_::compute_mul(carrier_uint(two_fc << beta), cache); |
3648 | | |
3649 | | // Deal with the unique exceptional cases |
3650 | | // 29711844 * 2^-82 |
3651 | | // = 6.1442653300000000008655037797566933477355632930994033813476... * 10^-18 |
3652 | | // and 29711844 * 2^-81 |
3653 | | // = 1.2288530660000000001731007559513386695471126586198806762695... * 10^-17 |
3654 | | // for binary32. |
3655 | | GLZ_JKJ_IF_CONSTEXPR(stdr::is_same<format, ieee754_binary32>::value) |
3656 | | { |
3657 | | if (binary_exponent <= -80) { |
3658 | | x_result.is_integer = false; |
3659 | | } |
3660 | | } |
3661 | | |
3662 | | if (!x_result.is_integer) { |
3663 | | ++x_result.integer_part; |
3664 | | } |
3665 | | |
3666 | | ////////////////////////////////////////////////////////////////////// |
3667 | | // Step 2: Try larger divisor; remove trailing zeros if necessary. |
3668 | | ////////////////////////////////////////////////////////////////////// |
3669 | | |
3670 | | constexpr auto big_divisor = compute_power<kappa + 1>(remainder_type_(10)); |
3671 | | |
3672 | | // Using an upper bound on xi, we might be able to optimize the division |
3673 | | // better than the compiler; we are computing xi / big_divisor here. |
3674 | | carrier_uint decimal_significand = |
3675 | | div::divide_by_pow10<kappa + 1, carrier_uint, |
3676 | | carrier_uint((carrier_uint(1) << (significand_bits + 1)) * big_divisor - 1)>( |
3677 | | x_result.integer_part); |
3678 | | auto r = remainder_type_(x_result.integer_part - big_divisor * decimal_significand); |
3679 | | |
3680 | | if (r != 0) { |
3681 | | ++decimal_significand; |
3682 | | r = remainder_type_(big_divisor - r); |
3683 | | } |
3684 | | |
3685 | | do { |
3686 | | if (r > deltai) { |
3687 | | break; |
3688 | | } |
3689 | | else if (r == deltai) { |
3690 | | // Compare the fractional parts. |
3691 | | // This branch is never taken for the exceptional cases |
3692 | | // 2f_c = 29711482, e = -81 |
3693 | | // (6.1442649164096937243516663440523473127541365101933479309082... * |
3694 | | // 10^-18) and 2f_c = 29711482, e = -80 |
3695 | | // (1.2288529832819387448703332688104694625508273020386695861816... * |
3696 | | // 10^-17). |
3697 | | // For the case of compressed cache for binary32, there is another |
3698 | | // exceptional case 2f_c = 33554430, e = -10 (16383.9990234375). In this |
3699 | | // case, the recovered cache is two large to make compute_mul_parity |
3700 | | // mistakenly conclude that z is not an integer, but actually z = 16384 is |
3701 | | // an integer. |
3702 | | GLZ_JKJ_IF_CONSTEXPR( |
3703 | | stdr::is_same<cache_holder_type, compressed_cache_holder<ieee754_binary32>>::value) |
3704 | | { |
3705 | | if (two_fc == 33554430 && binary_exponent == -10) { |
3706 | | break; |
3707 | | } |
3708 | | } |
3709 | | const auto z_result = |
3710 | | multiplication_traits_::compute_mul_parity(carrier_uint(two_fc + 2), cache, beta); |
3711 | | if (z_result.parity || z_result.is_integer) { |
3712 | | break; |
3713 | | } |
3714 | | } |
3715 | | |
3716 | | // The ceiling is inside, so we are done. |
3717 | | return SignPolicy::handle_sign(s, |
3718 | | TrailingZeroPolicy::template on_trailing_zeros<format>( |
3719 | | decimal_significand, decimal_exponent_type_(minus_k + kappa + 1))); |
3720 | | } while (false); |
3721 | | |
3722 | | ////////////////////////////////////////////////////////////////////// |
3723 | | // Step 3: Find the significand with the smaller divisor. |
3724 | | ////////////////////////////////////////////////////////////////////// |
3725 | | |
3726 | | decimal_significand *= 10; |
3727 | | decimal_significand -= div::small_division_by_pow10<kappa>(r); |
3728 | | return SignPolicy::handle_sign(s, TrailingZeroPolicy::template no_trailing_zeros<format>( |
3729 | | decimal_significand, decimal_exponent_type_(minus_k + kappa))); |
3730 | | } |
3731 | | |
3732 | | template <class SignPolicy, class TrailingZeroPolicy, class CachePolicy, class PreferredIntegerTypesPolicy> |
3733 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS static GLZ_JKJ_CONSTEXPR20 |
3734 | | return_type<SignPolicy, TrailingZeroPolicy, PreferredIntegerTypesPolicy> |
3735 | | compute_right_closed_directed(signed_significand_bits<FormatTraits> s, |
3736 | | exponent_int exponent_bits) noexcept |
3737 | | { |
3738 | | using cache_holder_type = typename CachePolicy::template cache_holder_type<format>; |
3739 | | static_assert(min_k >= cache_holder_type::min_k && max_k <= cache_holder_type::max_k, ""); |
3740 | | |
3741 | | using remainder_type_ = remainder_type<PreferredIntegerTypesPolicy>; |
3742 | | using decimal_exponent_type_ = decimal_exponent_type<PreferredIntegerTypesPolicy>; |
3743 | | using shift_amount_type = typename PreferredIntegerTypesPolicy::template shift_amount_type<FormatTraits>; |
3744 | | |
3745 | | using multiplication_traits_ = |
3746 | | multiplication_traits<FormatTraits, typename cache_holder_type::cache_entry_type, |
3747 | | cache_holder_type::cache_bits>; |
3748 | | |
3749 | | auto two_fc = s.remove_sign_bit_and_shift(); |
3750 | | auto binary_exponent = exponent_bits; |
3751 | | bool shorter_interval = false; |
3752 | | |
3753 | | // Is the input a normal number? |
3754 | | if (binary_exponent != 0) { |
3755 | | if (two_fc == 0 && binary_exponent != 1) { |
3756 | | shorter_interval = true; |
3757 | | } |
3758 | | binary_exponent += format::exponent_bias - format::significand_bits; |
3759 | | two_fc |= (carrier_uint(1) << (format::significand_bits + 1)); |
3760 | | } |
3761 | | // Is the input a subnormal number? |
3762 | | else { |
3763 | | binary_exponent = format::min_exponent - format::significand_bits; |
3764 | | } |
3765 | | |
3766 | | ////////////////////////////////////////////////////////////////////// |
3767 | | // Step 1: Schubfach multiplier calculation. |
3768 | | ////////////////////////////////////////////////////////////////////// |
3769 | | |
3770 | | // Compute k and beta. |
3771 | | const auto minus_k = decimal_exponent_type_( |
3772 | | log::floor_log10_pow2<format::min_exponent - format::significand_bits, |
3773 | | format::max_exponent - format::significand_bits, decimal_exponent_type_>( |
3774 | | exponent_int(binary_exponent - (shorter_interval ? 1 : 0))) - |
3775 | | kappa); |
3776 | | const auto cache = |
3777 | | CachePolicy::template get_cache<format, shift_amount_type>(decimal_exponent_type_(-minus_k)); |
3778 | | const auto beta = |
3779 | | shift_amount_type(binary_exponent + log::floor_log2_pow10(decimal_exponent_type_(-minus_k))); |
3780 | | |
3781 | | // Compute zi and deltai. |
3782 | | // 10^kappa <= deltai < 10^(kappa + 1) |
3783 | | const auto deltai = static_cast<remainder_type_>( |
3784 | | multiplication_traits_::compute_delta(cache, shift_amount_type(beta - (shorter_interval ? 1 : 0)))); |
3785 | | const carrier_uint zi = |
3786 | | multiplication_traits_::compute_mul(carrier_uint(two_fc << beta), cache).integer_part; |
3787 | | |
3788 | | ////////////////////////////////////////////////////////////////////// |
3789 | | // Step 2: Try larger divisor; remove trailing zeros if necessary. |
3790 | | ////////////////////////////////////////////////////////////////////// |
3791 | | |
3792 | | constexpr auto big_divisor = compute_power<kappa + 1>(remainder_type_(10)); |
3793 | | |
3794 | | // Using an upper bound on zi, we might be able to optimize the division better |
3795 | | // than the compiler; we are computing zi / big_divisor here. |
3796 | | carrier_uint decimal_significand = |
3797 | | div::divide_by_pow10<kappa + 1, carrier_uint, |
3798 | | carrier_uint((carrier_uint(1) << (significand_bits + 1)) * big_divisor - 1)>(zi); |
3799 | | const auto r = remainder_type_(zi - big_divisor * decimal_significand); |
3800 | | |
3801 | | do { |
3802 | | if (r > deltai) { |
3803 | | break; |
3804 | | } |
3805 | | else if (r == deltai) { |
3806 | | // Compare the fractional parts. |
3807 | | if (!multiplication_traits_::compute_mul_parity(carrier_uint(two_fc - (shorter_interval ? 1 : 2)), |
3808 | | cache, beta) |
3809 | | .parity) { |
3810 | | break; |
3811 | | } |
3812 | | } |
3813 | | |
3814 | | // The floor is inside, so we are done. |
3815 | | return SignPolicy::handle_sign(s, |
3816 | | TrailingZeroPolicy::template on_trailing_zeros<format>( |
3817 | | decimal_significand, decimal_exponent_type_(minus_k + kappa + 1))); |
3818 | | } while (false); |
3819 | | |
3820 | | ////////////////////////////////////////////////////////////////////// |
3821 | | // Step 3: Find the significand with the small divisor. |
3822 | | ////////////////////////////////////////////////////////////////////// |
3823 | | |
3824 | | decimal_significand *= 10; |
3825 | | decimal_significand += div::small_division_by_pow10<kappa>(r); |
3826 | | return SignPolicy::handle_sign(s, TrailingZeroPolicy::template no_trailing_zeros<format>( |
3827 | | decimal_significand, decimal_exponent_type_(minus_k + kappa))); |
3828 | | } |
3829 | | |
3830 | | static constexpr bool is_right_endpoint_integer_shorter_interval(exponent_int binary_exponent) noexcept |
3831 | 0 | { |
3832 | 0 | return binary_exponent >= case_shorter_interval_right_endpoint_lower_threshold && |
3833 | 0 | binary_exponent <= case_shorter_interval_right_endpoint_upper_threshold; |
3834 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::is_right_endpoint_integer_shorter_interval(int) Unexecuted instantiation: glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::is_right_endpoint_integer_shorter_interval(int) |
3835 | | |
3836 | | static constexpr bool is_left_endpoint_integer_shorter_interval(exponent_int binary_exponent) noexcept |
3837 | 0 | { |
3838 | 0 | return binary_exponent >= case_shorter_interval_left_endpoint_lower_threshold && |
3839 | 0 | binary_exponent <= case_shorter_interval_left_endpoint_upper_threshold; |
3840 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::is_left_endpoint_integer_shorter_interval(int) Unexecuted instantiation: glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::is_left_endpoint_integer_shorter_interval(int) |
3841 | | }; |
3842 | | |
3843 | | //////////////////////////////////////////////////////////////////////////////////////// |
3844 | | // Policy holder. |
3845 | | //////////////////////////////////////////////////////////////////////////////////////// |
3846 | | |
3847 | | // The library will specify a list of accepted kinds of policies and their defaults, |
3848 | | // and the user will pass a list of policies parameters. The policy parameters are |
3849 | | // supposed to be stateless and only convey information through their types. |
3850 | | // The aim of the helper classes/functions given below is to do the following: |
3851 | | // 1. Check if the policy parameters given by the user are all valid; that means, |
3852 | | // each of them should be at least of one of the kinds specified by the library. |
3853 | | // If that's not the case, then the compilation fails. |
3854 | | // 2. Check if multiple policy parameters for the same kind is specified by the |
3855 | | // user. If that's the case, then the compilation fails. |
3856 | | // 3. Build a class deriving from all policies the user have given, and also from |
3857 | | // the default policies if the user did not specify one for some kinds. |
3858 | | // The library considers a certain policy parameter to belong to a specific kind if and only |
3859 | | // if the parameter's type has a member type with a specific name; for example, it belongs |
3860 | | // to "sign policy" kind if there is a member type sign_policy. |
3861 | | |
3862 | | // For a given kind, find a policy belonging to that kind. |
3863 | | // Check if there are more than one such policies. |
3864 | | enum class policy_found_info { not_found, unique, repeated }; |
3865 | | template <class Policy, policy_found_info info> |
3866 | | struct found_policy_pair |
3867 | | { |
3868 | | // Either the policy parameter type given by the user, or the default policy. |
3869 | | using policy = Policy; |
3870 | | static constexpr auto found_info = info; |
3871 | | }; |
3872 | | |
3873 | | template <class KindDetector, class DefaultPolicy> |
3874 | | struct detector_default_pair |
3875 | | { |
3876 | | using kind_detector = KindDetector; |
3877 | | |
3878 | | // Iterate through all given policy parameter types and see if there is a policy |
3879 | | // parameter type belonging to the policy kind specified by KindDetector. |
3880 | | // 1. If there is none, get_found_policy_pair returns |
3881 | | // found_policy_pair<DefaultPolicy, policy_found_info::not_found>. |
3882 | | // 2. If there is only one parameter type belonging to the specified kind, then |
3883 | | // get_found_policy_pair returns |
3884 | | // found_policy_pair<Policy, policy_found_info::unique> |
3885 | | // where Policy is the unique parameter type belonging to the specified kind. |
3886 | | // 3. If there are multiple parameter types belonging to the specified kind, then |
3887 | | // get_found_policy_pair returns |
3888 | | // found_policy_pair<FirstPolicy, policy_found_info::repeated> |
3889 | | // where FirstPolicy is the first parameter type belonging to the specified kind. |
3890 | | // The compilation must fail if this happens. |
3891 | | // This is done by first setting FoundPolicyInfo below to |
3892 | | // found_policy_pair<DefaultPolicy, policy_found_info::not_found>, and then iterate |
3893 | | // over Policies, replacing FoundPolicyInfo by the appropriate one if a parameter |
3894 | | // type belonging to the specified kind is found. |
3895 | | |
3896 | | template <class FoundPolicyInfo, class... Policies> |
3897 | | struct get_found_policy_pair_impl; |
3898 | | |
3899 | | template <class FoundPolicyInfo> |
3900 | | struct get_found_policy_pair_impl<FoundPolicyInfo> |
3901 | | { |
3902 | | using type = FoundPolicyInfo; |
3903 | | }; |
3904 | | |
3905 | | template <class FoundPolicyInfo, class FirstPolicy, class... RemainingPolicies> |
3906 | | struct get_found_policy_pair_impl<FoundPolicyInfo, FirstPolicy, RemainingPolicies...> |
3907 | | { |
3908 | | using type = typename stdr::conditional< |
3909 | | KindDetector{}(dummy<FirstPolicy>{}), |
3910 | | typename stdr::conditional< |
3911 | | FoundPolicyInfo::found_info == policy_found_info::not_found, |
3912 | | typename get_found_policy_pair_impl<found_policy_pair<FirstPolicy, policy_found_info::unique>, |
3913 | | RemainingPolicies...>::type, |
3914 | | typename get_found_policy_pair_impl<found_policy_pair<FirstPolicy, policy_found_info::repeated>, |
3915 | | RemainingPolicies...>::type>::type, |
3916 | | typename get_found_policy_pair_impl<FoundPolicyInfo, RemainingPolicies...>::type>::type; |
3917 | | }; |
3918 | | |
3919 | | template <class... Policies> |
3920 | | using get_found_policy_pair = |
3921 | | typename get_found_policy_pair_impl<found_policy_pair<DefaultPolicy, policy_found_info::not_found>, |
3922 | | Policies...>::type; |
3923 | | }; |
3924 | | |
3925 | | // Simple typelist of detector_default_pair's. |
3926 | | template <class... DetectorDefaultPairs> |
3927 | | struct detector_default_pair_list |
3928 | | {}; |
3929 | | |
3930 | | // Check if a given policy belongs to one of the kinds specified by the library. |
3931 | | template <class Policy> |
3932 | | constexpr bool check_policy_validity(dummy<Policy>, detector_default_pair_list<>) noexcept |
3933 | 0 | { |
3934 | 0 | return false; |
3935 | 0 | } Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::sign::ignore_t>(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::sign::ignore_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<>) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::trailing_zero::ignore_t>(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::ignore_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<>) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::trailing_zero::remove_t>(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<>) |
3936 | | template <class Policy, class FirstDetectorDefaultPair, class... RemainingDetectorDefaultPairs> |
3937 | | constexpr bool check_policy_validity( |
3938 | | dummy<Policy>, |
3939 | | detector_default_pair_list<FirstDetectorDefaultPair, RemainingDetectorDefaultPairs...>) noexcept |
3940 | 0 | { |
3941 | 0 | return |
3942 | 0 | typename FirstDetectorDefaultPair::kind_detector{}(dummy<Policy>{}) || |
3943 | 0 | check_policy_validity(dummy<Policy>{}, detector_default_pair_list<RemainingDetectorDefaultPairs...>{}); |
3944 | 0 | } Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t>>(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::sign::ignore_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t>>) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::sign::ignore_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::sign::ignore_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::sign::ignore_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::sign::ignore_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::sign::ignore_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::trailing_zero::ignore_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t>>(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::ignore_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t>>) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::trailing_zero::ignore_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::ignore_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::trailing_zero::ignore_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::ignore_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::trailing_zero::ignore_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::ignore_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::trailing_zero::ignore_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::ignore_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::trailing_zero::ignore_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::ignore_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::trailing_zero::remove_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t>>(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t>>) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::trailing_zero::remove_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::trailing_zero::remove_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::trailing_zero::remove_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::trailing_zero::remove_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_validity<glz::jkj::dragonbox::policy::trailing_zero::remove_t, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >) |
3945 | | |
3946 | | // Check if all of policies belong to some of the kinds specified by the library. |
3947 | | template <class DetectorDefaultPairList> |
3948 | | constexpr bool check_policy_list_validity(DetectorDefaultPairList) noexcept |
3949 | 0 | { |
3950 | 0 | return true; |
3951 | 0 | } |
3952 | | template <class DetectorDefaultPairList, class FirstPolicy, class... RemainingPolicies> |
3953 | | constexpr bool check_policy_list_validity(DetectorDefaultPairList, dummy<FirstPolicy> first_policy, |
3954 | | dummy<RemainingPolicies>... remaining_policies) |
3955 | 0 | { |
3956 | 0 | return check_policy_validity(first_policy, DetectorDefaultPairList{}) && |
3957 | 0 | check_policy_list_validity(DetectorDefaultPairList{}, remaining_policies...); |
3958 | 0 | } Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_list_validity<glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::policy::trailing_zero::ignore_t>(glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::ignore_t>) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_list_validity<glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::ignore_t>(glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::sign::ignore_t>, glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::ignore_t>) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_list_validity<glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::policy::trailing_zero::remove_t>(glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::remove_t>) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::check_policy_list_validity<glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::remove_t>(glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::sign::ignore_t>, glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::remove_t>) |
3959 | | |
3960 | | // Actual policy holder class deriving from all specified policy types. |
3961 | | template <class... Policies> |
3962 | | struct policy_holder : Policies... |
3963 | | {}; |
3964 | | |
3965 | | // Iterate through the library-specified list of base-default pairs, i.e., the list of |
3966 | | // policy kinds and their defaults. For each base-default pair, call |
3967 | | // base_default_pair::get_found_policy_pair on the list of user-specified list of |
3968 | | // policies to get found_policy_pair, and build the list of them. |
3969 | | |
3970 | | template <bool repeated_, class... FoundPolicyPairs> |
3971 | | struct found_policy_pair_list |
3972 | | { |
3973 | | // This will be set to be true if and only if there exists at least one |
3974 | | // found_policy_pair inside FoundPolicyPairs with |
3975 | | // found_info == policy_found_info::repeated, in which case the compilation must |
3976 | | // fail. |
3977 | | static constexpr bool repeated = repeated_; |
3978 | | }; |
3979 | | |
3980 | | // Iterate through DetectorDefaultPairList and augment FoundPolicyPairList by one at each |
3981 | | // iteration. |
3982 | | template <class DetectorDefaultPairList, class FoundPolicyPairList, class... Policies> |
3983 | | struct make_policy_pair_list_impl; |
3984 | | |
3985 | | // When there is no more detector-default pair to iterate, then the current |
3986 | | // found_policy_pair_list is the final result. |
3987 | | template <bool repeated, class... FoundPolicyPairs, class... Policies> |
3988 | | struct make_policy_pair_list_impl<detector_default_pair_list<>, |
3989 | | found_policy_pair_list<repeated, FoundPolicyPairs...>, Policies...> |
3990 | | { |
3991 | | using type = found_policy_pair_list<repeated, FoundPolicyPairs...>; |
3992 | | }; |
3993 | | |
3994 | | // For the first detector-default pair in the remaining list, call |
3995 | | // detector_default_pair::get_found_policy_pair on Policies and add the returned |
3996 | | // found_policy_pair into the current list of found_policy_pair's, and move to the next |
3997 | | // detector-default pair. |
3998 | | template <class FirstDetectorDefaultPair, class... RemainingDetectorDefaultPairs, bool repeated, |
3999 | | class... FoundPolicyPairs, class... Policies> |
4000 | | struct make_policy_pair_list_impl< |
4001 | | detector_default_pair_list<FirstDetectorDefaultPair, RemainingDetectorDefaultPairs...>, |
4002 | | found_policy_pair_list<repeated, FoundPolicyPairs...>, Policies...> |
4003 | | { |
4004 | | using new_found_policy_pair = |
4005 | | typename FirstDetectorDefaultPair::template get_found_policy_pair<Policies...>; |
4006 | | |
4007 | | using type = typename make_policy_pair_list_impl< |
4008 | | detector_default_pair_list<RemainingDetectorDefaultPairs...>, |
4009 | | found_policy_pair_list<(repeated || new_found_policy_pair::found_info == policy_found_info::repeated), |
4010 | | new_found_policy_pair, FoundPolicyPairs...>, |
4011 | | Policies...>::type; |
4012 | | }; |
4013 | | |
4014 | | template <class DetectorDefaultPairList, class... Policies> |
4015 | | using policy_pair_list = typename make_policy_pair_list_impl<DetectorDefaultPairList, |
4016 | | found_policy_pair_list<false>, Policies...>::type; |
4017 | | |
4018 | | // Unpack FoundPolicyPairList into found_policy_pair's and build the policy_holder type |
4019 | | // from the corresponding typelist of found_policy_pair::policy's. |
4020 | | template <class FoundPolicyPairList, class... RawPolicies> |
4021 | | struct convert_to_policy_holder_impl; |
4022 | | |
4023 | | template <bool repeated, class... RawPolicies> |
4024 | | struct convert_to_policy_holder_impl<found_policy_pair_list<repeated>, RawPolicies...> |
4025 | | { |
4026 | | using type = policy_holder<RawPolicies...>; |
4027 | | }; |
4028 | | |
4029 | | template <bool repeated, class FirstFoundPolicyPair, class... RemainingFoundPolicyPairs, class... RawPolicies> |
4030 | | struct convert_to_policy_holder_impl< |
4031 | | found_policy_pair_list<repeated, FirstFoundPolicyPair, RemainingFoundPolicyPairs...>, RawPolicies...> |
4032 | | { |
4033 | | using type = |
4034 | | typename convert_to_policy_holder_impl<found_policy_pair_list<repeated, RemainingFoundPolicyPairs...>, |
4035 | | typename FirstFoundPolicyPair::policy, RawPolicies...>::type; |
4036 | | }; |
4037 | | |
4038 | | template <class FoundPolicyPairList> |
4039 | | using convert_to_policy_holder = typename convert_to_policy_holder_impl<FoundPolicyPairList>::type; |
4040 | | |
4041 | | template <class DetectorDefaultPairList, class... Policies> |
4042 | | struct make_policy_holder_impl |
4043 | | { |
4044 | | static_assert(check_policy_list_validity(DetectorDefaultPairList{}, dummy<Policies>{}...), |
4045 | | "jkj::dragonbox: an invalid policy is specified"); |
4046 | | |
4047 | | static_assert(!policy_pair_list<DetectorDefaultPairList, Policies...>::repeated, |
4048 | | "jkj::dragonbox: at most one policy should be specified for each policy kind"); |
4049 | | |
4050 | | using type = convert_to_policy_holder<policy_pair_list<DetectorDefaultPairList, Policies...>>; |
4051 | | }; |
4052 | | |
4053 | | template <class DetectorDefaultPairList, class... Policies> |
4054 | | using make_policy_holder = typename make_policy_holder_impl<DetectorDefaultPairList, Policies...>::type; |
4055 | | |
4056 | | // Policy kind detectors. |
4057 | | struct is_sign_policy |
4058 | | { |
4059 | 0 | constexpr bool operator()(...) noexcept { return false; } |
4060 | | template <class Policy, class = typename Policy::sign_policy> |
4061 | | constexpr bool operator()(dummy<Policy>) noexcept |
4062 | 0 | { |
4063 | 0 | return true; |
4064 | 0 | } |
4065 | | }; |
4066 | | struct is_trailing_zero_policy |
4067 | | { |
4068 | 0 | constexpr bool operator()(...) noexcept { return false; } |
4069 | | template <class Policy, class = typename Policy::trailing_zero_policy> |
4070 | | constexpr bool operator()(dummy<Policy>) noexcept |
4071 | 0 | { |
4072 | 0 | return true; |
4073 | 0 | } Unexecuted instantiation: bool glz::jkj::dragonbox::detail::is_trailing_zero_policy::operator()<glz::jkj::dragonbox::policy::trailing_zero::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::ignore_t>(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::ignore_t>) Unexecuted instantiation: bool glz::jkj::dragonbox::detail::is_trailing_zero_policy::operator()<glz::jkj::dragonbox::policy::trailing_zero::remove_t, glz::jkj::dragonbox::policy::trailing_zero::remove_t>(glz::jkj::dragonbox::detail::dummy<glz::jkj::dragonbox::policy::trailing_zero::remove_t>) |
4074 | | }; |
4075 | | struct is_decimal_to_binary_rounding_policy |
4076 | | { |
4077 | 0 | constexpr bool operator()(...) noexcept { return false; } |
4078 | | template <class Policy, class = typename Policy::decimal_to_binary_rounding_policy> |
4079 | | constexpr bool operator()(dummy<Policy>) noexcept |
4080 | | { |
4081 | | return true; |
4082 | | } |
4083 | | }; |
4084 | | struct is_binary_to_decimal_rounding_policy |
4085 | | { |
4086 | 0 | constexpr bool operator()(...) noexcept { return false; } |
4087 | | template <class Policy, class = typename Policy::binary_to_decimal_rounding_policy> |
4088 | | constexpr bool operator()(dummy<Policy>) noexcept |
4089 | | { |
4090 | | return true; |
4091 | | } |
4092 | | }; |
4093 | | struct is_cache_policy |
4094 | | { |
4095 | 0 | constexpr bool operator()(...) noexcept { return false; } |
4096 | | template <class Policy, class = typename Policy::cache_policy> |
4097 | | constexpr bool operator()(dummy<Policy>) noexcept |
4098 | | { |
4099 | | return true; |
4100 | | } |
4101 | | }; |
4102 | | struct is_preferred_integer_types_policy |
4103 | | { |
4104 | 0 | constexpr bool operator()(...) noexcept { return false; } |
4105 | | template <class Policy, class = typename Policy::preferred_integer_types_policy> |
4106 | | constexpr bool operator()(dummy<Policy>) noexcept |
4107 | | { |
4108 | | return true; |
4109 | | } |
4110 | | }; |
4111 | | |
4112 | | template <class... Policies> |
4113 | | using to_decimal_policy_holder = make_policy_holder< |
4114 | | detector_default_pair_list< |
4115 | | detector_default_pair<is_sign_policy, policy::sign::return_sign_t>, |
4116 | | detector_default_pair<is_trailing_zero_policy, policy::trailing_zero::remove_t>, |
4117 | | detector_default_pair<is_decimal_to_binary_rounding_policy, |
4118 | | policy::decimal_to_binary_rounding::nearest_to_even_t>, |
4119 | | detector_default_pair<is_binary_to_decimal_rounding_policy, |
4120 | | policy::binary_to_decimal_rounding::to_even_t>, |
4121 | | detector_default_pair<is_cache_policy, policy::cache::full_t>, |
4122 | | detector_default_pair<is_preferred_integer_types_policy, policy::preferred_integer_types::match_t>>, |
4123 | | Policies...>; |
4124 | | |
4125 | | template <class FormatTraits, class... Policies> |
4126 | | using to_decimal_return_type = typename impl<FormatTraits>::template return_type< |
4127 | | typename to_decimal_policy_holder<Policies...>::sign_policy, |
4128 | | typename to_decimal_policy_holder<Policies...>::trailing_zero_policy, |
4129 | | typename to_decimal_policy_holder<Policies...>::preferred_integer_types_policy>; |
4130 | | |
4131 | | template <class FormatTraits, class PolicyHolder> |
4132 | | struct to_decimal_dispatcher |
4133 | | { |
4134 | | using sign_policy = typename PolicyHolder::sign_policy; |
4135 | | using trailing_zero_policy = typename PolicyHolder::trailing_zero_policy; |
4136 | | using binary_to_decimal_rounding_policy = typename PolicyHolder::binary_to_decimal_rounding_policy; |
4137 | | using cache_policy = typename PolicyHolder::cache_policy; |
4138 | | using preferred_integer_types_policy = typename PolicyHolder::preferred_integer_types_policy; |
4139 | | using return_type = typename impl<FormatTraits>::template return_type<sign_policy, trailing_zero_policy, |
4140 | | preferred_integer_types_policy>; |
4141 | | |
4142 | | template <class IntervalTypeProvider> |
4143 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS GLZ_JKJ_CONSTEXPR20 return_type |
4144 | | operator()(IntervalTypeProvider, signed_significand_bits<FormatTraits> s, |
4145 | | typename FormatTraits::exponent_int exponent_bits) noexcept |
4146 | 0 | { |
4147 | 0 | constexpr auto tag = IntervalTypeProvider::tag; |
4148 | 0 |
|
4149 | 0 | GLZ_JKJ_IF_CONSTEXPR(tag == policy::decimal_to_binary_rounding::tag_t::to_nearest) |
4150 | 0 | { |
4151 | 0 | return impl<FormatTraits>::template compute_nearest< |
4152 | 0 | sign_policy, trailing_zero_policy, IntervalTypeProvider, binary_to_decimal_rounding_policy, |
4153 | 0 | cache_policy, preferred_integer_types_policy>(s, exponent_bits); |
4154 | 0 | } |
4155 | 0 | else GLZ_JKJ_IF_CONSTEXPR(tag == policy::decimal_to_binary_rounding::tag_t::left_closed_directed) |
4156 | 0 | { |
4157 | 0 | return impl<FormatTraits>::template compute_left_closed_directed< |
4158 | 0 | sign_policy, trailing_zero_policy, cache_policy, preferred_integer_types_policy>(s, exponent_bits); |
4159 | 0 | } |
4160 | 0 | else |
4161 | 0 | { |
4162 | 0 | #if GLZ_JKJ_HAS_IF_CONSTEXPR |
4163 | 0 | static_assert(tag == policy::decimal_to_binary_rounding::tag_t::right_closed_directed, ""); |
4164 | 0 | #endif |
4165 | 0 | return impl<FormatTraits>::template compute_right_closed_directed< |
4166 | 0 | sign_policy, trailing_zero_policy, cache_policy, preferred_integer_types_policy>(s, exponent_bits); |
4167 | 0 | } |
4168 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::decimal_fp<unsigned long, int, false, false> glz::jkj::dragonbox::detail::to_decimal_dispatcher<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int>, glz::jkj::dragonbox::detail::policy_holder<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::ignore_t, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t, glz::jkj::dragonbox::policy::cache::full_t, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >::operator()<glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>(glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t, glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >, int) Unexecuted instantiation: glz::jkj::dragonbox::decimal_fp<unsigned int, int, false, false> glz::jkj::dragonbox::detail::to_decimal_dispatcher<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int>, glz::jkj::dragonbox::detail::policy_holder<glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::remove_t, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t, glz::jkj::dragonbox::policy::cache::full_t, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >::operator()<glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>(glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t, glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >, int) |
4169 | | }; |
4170 | | } |
4171 | | |
4172 | | //////////////////////////////////////////////////////////////////////////////////////// |
4173 | | // The interface function. |
4174 | | //////////////////////////////////////////////////////////////////////////////////////// |
4175 | | |
4176 | | template <class FormatTraits, class ExponentBits, class... Policies> |
4177 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS GLZ_JKJ_CONSTEXPR20 |
4178 | | detail::to_decimal_return_type<FormatTraits, Policies...> |
4179 | | to_decimal_ex(signed_significand_bits<FormatTraits> s, ExponentBits exponent_bits, Policies...) noexcept |
4180 | 0 | { |
4181 | 0 | // Build policy holder type. |
4182 | 0 | using policy_holder = detail::to_decimal_policy_holder<Policies...>; |
4183 | 0 |
|
4184 | 0 | return policy_holder::delegate(s, detail::to_decimal_dispatcher<FormatTraits, policy_holder>{}, s, |
4185 | 0 | exponent_bits); |
4186 | 0 | } Unexecuted instantiation: glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >::return_type<glz::jkj::dragonbox::detail::make_policy_holder_impl<glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::ignore_t>::type::sign_policy, glz::jkj::dragonbox::detail::make_policy_holder_impl<glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::ignore_t>::type::trailing_zero_policy, glz::jkj::dragonbox::detail::make_policy_holder_impl<glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::ignore_t>::type::preferred_integer_types_policy> glz::jkj::dragonbox::to_decimal_ex<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int>, int, glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::ignore_t>(glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary64, unsigned long, int> >, int, glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::ignore_t) Unexecuted instantiation: glz::jkj::dragonbox::detail::impl<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >::return_type<glz::jkj::dragonbox::detail::make_policy_holder_impl<glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::remove_t>::type::sign_policy, glz::jkj::dragonbox::detail::make_policy_holder_impl<glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::remove_t>::type::trailing_zero_policy, glz::jkj::dragonbox::detail::make_policy_holder_impl<glz::jkj::dragonbox::detail::detector_default_pair_list<glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_sign_policy, glz::jkj::dragonbox::policy::sign::return_sign_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_trailing_zero_policy, glz::jkj::dragonbox::policy::trailing_zero::remove_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_decimal_to_binary_rounding_policy, glz::jkj::dragonbox::policy::decimal_to_binary_rounding::nearest_to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_binary_to_decimal_rounding_policy, glz::jkj::dragonbox::policy::binary_to_decimal_rounding::to_even_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_cache_policy, glz::jkj::dragonbox::policy::cache::full_t>, glz::jkj::dragonbox::detail::detector_default_pair<glz::jkj::dragonbox::detail::is_preferred_integer_types_policy, glz::jkj::dragonbox::policy::preferred_integer_types::match_t> >, glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::remove_t>::type::preferred_integer_types_policy> glz::jkj::dragonbox::to_decimal_ex<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int>, int, glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::remove_t>(glz::jkj::dragonbox::signed_significand_bits<glz::jkj::dragonbox::ieee754_binary_traits<glz::jkj::dragonbox::ieee754_binary32, unsigned int, int> >, int, glz::jkj::dragonbox::policy::sign::ignore_t, glz::jkj::dragonbox::policy::trailing_zero::remove_t) |
4187 | | |
4188 | | template <class Float, class ConversionTraits = default_float_bit_carrier_conversion_traits<Float>, |
4189 | | class FormatTraits = |
4190 | | ieee754_binary_traits<typename ConversionTraits::format, typename ConversionTraits::carrier_uint>, |
4191 | | class... Policies> |
4192 | | GLZ_JKJ_FORCEINLINE GLZ_JKJ_SAFEBUFFERS GLZ_JKJ_CONSTEXPR20 |
4193 | | detail::to_decimal_return_type<FormatTraits, Policies...> |
4194 | | to_decimal(Float x, Policies... policies) noexcept |
4195 | | { |
4196 | | const auto br = make_float_bits<Float, ConversionTraits, FormatTraits>(x); |
4197 | | const auto exponent_bits = br.extract_exponent_bits(); |
4198 | | const auto s = br.remove_exponent_bits(); |
4199 | | assert(br.is_finite() && br.is_nonzero()); |
4200 | | |
4201 | | return to_decimal_ex(s, exponent_bits, policies...); |
4202 | | } |
4203 | | } |
4204 | | } |
4205 | | |
4206 | | #undef GLZ_JKJ_HAS_BUILTIN |
4207 | | #undef GLZ_JKJ_FORCEINLINE |
4208 | | #undef GLZ_JKJ_SAFEBUFFERS |
4209 | | #undef GLZ_JKJ_CONSTEXPR20 |
4210 | | #undef GLZ_JKJ_USE_IS_CONSTANT_EVALUATED |
4211 | | #undef GLZ_JKJ_CAN_BRANCH_ON_CONSTEVAL |
4212 | | #undef GLZ_JKJ_IF_NOT_CONSTEVAL |
4213 | | #undef GLZ_JKJ_IF_CONSTEVAL |
4214 | | #undef GLZ_JKJ_HAS_BIT_CAST |
4215 | | #undef GLZ_JKJ_IF_CONSTEXPR |
4216 | | #undef GLZ_JKJ_HAS_IF_CONSTEXPR |
4217 | | #undef GLZ_JKJ_INLINE_VARIABLE |
4218 | | #undef GLZ_JKJ_HAS_INLINE_VARIABLE |
4219 | | #undef GLZ_JKJ_HAS_CONSTEXPR17 |
4220 | | #undef GLZ_JKJ_CONSTEXPR14 |
4221 | | #undef GLZ_JKJ_HAS_CONSTEXPR14 |
4222 | | #if GLZ_JKJ_STD_REPLACEMENT_NAMESPACE_DEFINED |
4223 | | #undef GLZ_JKJ_STD_REPLACEMENT_NAMESPACE_DEFINED |
4224 | | #else |
4225 | | #undef GLZ_JKJ_STD_REPLACEMENT_NAMESPACE |
4226 | | #endif |
4227 | | #if GLZ_JKJ_STATIC_DATA_SECTION_DEFINED |
4228 | | #undef GLZ_JKJ_STATIC_DATA_SECTION_DEFINED |
4229 | | #else |
4230 | | #undef GLZ_JKJ_STATIC_DATA_SECTION |
4231 | | #endif |
4232 | | |
4233 | | #endif |