@lucent-lang/lucent 0.0.4 → 0.1.0

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