mqt-core 3.3.2__cp313-cp313t-win_amd64.whl

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 (537) hide show
  1. mqt/core/__init__.py +89 -0
  2. mqt/core/__main__.py +55 -0
  3. mqt/core/_commands.py +52 -0
  4. mqt/core/_compat/__init__.py +11 -0
  5. mqt/core/_compat/typing.py +29 -0
  6. mqt/core/_version.py +34 -0
  7. mqt/core/_version.pyi +12 -0
  8. mqt/core/bin/mqt-core-algorithms.dll +0 -0
  9. mqt/core/bin/mqt-core-circuit-optimizer.dll +0 -0
  10. mqt/core/bin/mqt-core-dd.dll +0 -0
  11. mqt/core/bin/mqt-core-ds.dll +0 -0
  12. mqt/core/bin/mqt-core-fomac.dll +0 -0
  13. mqt/core/bin/mqt-core-ir.dll +0 -0
  14. mqt/core/bin/mqt-core-na-fomac.dll +0 -0
  15. mqt/core/bin/mqt-core-na.dll +0 -0
  16. mqt/core/bin/mqt-core-qasm.dll +0 -0
  17. mqt/core/bin/mqt-core-qdmi-driver.dll +0 -0
  18. mqt/core/bin/mqt-core-qdmi-na-device.dll +0 -0
  19. mqt/core/bin/mqt-core-zx.dll +0 -0
  20. mqt/core/dd.cp313t-win_amd64.pyd +0 -0
  21. mqt/core/dd.pyi +1016 -0
  22. mqt/core/dd_evaluation.py +368 -0
  23. mqt/core/fomac.cp313t-win_amd64.pyd +0 -0
  24. mqt/core/fomac.pyi +125 -0
  25. mqt/core/include/mqt-core/algorithms/BernsteinVazirani.hpp +39 -0
  26. mqt/core/include/mqt-core/algorithms/GHZState.hpp +18 -0
  27. mqt/core/include/mqt-core/algorithms/Grover.hpp +33 -0
  28. mqt/core/include/mqt-core/algorithms/QFT.hpp +21 -0
  29. mqt/core/include/mqt-core/algorithms/QPE.hpp +30 -0
  30. mqt/core/include/mqt-core/algorithms/RandomCliffordCircuit.hpp +22 -0
  31. mqt/core/include/mqt-core/algorithms/StatePreparation.hpp +43 -0
  32. mqt/core/include/mqt-core/algorithms/WState.hpp +18 -0
  33. mqt/core/include/mqt-core/algorithms/mqt_core_algorithms_export.h +43 -0
  34. mqt/core/include/mqt-core/boost/config/abi/borland_prefix.hpp +27 -0
  35. mqt/core/include/mqt-core/boost/config/abi/borland_suffix.hpp +12 -0
  36. mqt/core/include/mqt-core/boost/config/abi/msvc_prefix.hpp +22 -0
  37. mqt/core/include/mqt-core/boost/config/abi/msvc_suffix.hpp +8 -0
  38. mqt/core/include/mqt-core/boost/config/abi_prefix.hpp +25 -0
  39. mqt/core/include/mqt-core/boost/config/abi_suffix.hpp +25 -0
  40. mqt/core/include/mqt-core/boost/config/assert_cxx03.hpp +211 -0
  41. mqt/core/include/mqt-core/boost/config/assert_cxx11.hpp +212 -0
  42. mqt/core/include/mqt-core/boost/config/assert_cxx14.hpp +47 -0
  43. mqt/core/include/mqt-core/boost/config/assert_cxx17.hpp +65 -0
  44. mqt/core/include/mqt-core/boost/config/assert_cxx20.hpp +59 -0
  45. mqt/core/include/mqt-core/boost/config/assert_cxx23.hpp +41 -0
  46. mqt/core/include/mqt-core/boost/config/assert_cxx98.hpp +23 -0
  47. mqt/core/include/mqt-core/boost/config/auto_link.hpp +525 -0
  48. mqt/core/include/mqt-core/boost/config/compiler/borland.hpp +342 -0
  49. mqt/core/include/mqt-core/boost/config/compiler/clang.hpp +370 -0
  50. mqt/core/include/mqt-core/boost/config/compiler/clang_version.hpp +89 -0
  51. mqt/core/include/mqt-core/boost/config/compiler/codegear.hpp +389 -0
  52. mqt/core/include/mqt-core/boost/config/compiler/comeau.hpp +59 -0
  53. mqt/core/include/mqt-core/boost/config/compiler/common_edg.hpp +185 -0
  54. mqt/core/include/mqt-core/boost/config/compiler/compaq_cxx.hpp +19 -0
  55. mqt/core/include/mqt-core/boost/config/compiler/cray.hpp +446 -0
  56. mqt/core/include/mqt-core/boost/config/compiler/diab.hpp +26 -0
  57. mqt/core/include/mqt-core/boost/config/compiler/digitalmars.hpp +146 -0
  58. mqt/core/include/mqt-core/boost/config/compiler/gcc.hpp +386 -0
  59. mqt/core/include/mqt-core/boost/config/compiler/gcc_xml.hpp +115 -0
  60. mqt/core/include/mqt-core/boost/config/compiler/greenhills.hpp +28 -0
  61. mqt/core/include/mqt-core/boost/config/compiler/hp_acc.hpp +153 -0
  62. mqt/core/include/mqt-core/boost/config/compiler/intel.hpp +577 -0
  63. mqt/core/include/mqt-core/boost/config/compiler/kai.hpp +33 -0
  64. mqt/core/include/mqt-core/boost/config/compiler/metrowerks.hpp +201 -0
  65. mqt/core/include/mqt-core/boost/config/compiler/mpw.hpp +143 -0
  66. mqt/core/include/mqt-core/boost/config/compiler/nvcc.hpp +64 -0
  67. mqt/core/include/mqt-core/boost/config/compiler/pathscale.hpp +141 -0
  68. mqt/core/include/mqt-core/boost/config/compiler/pgi.hpp +23 -0
  69. mqt/core/include/mqt-core/boost/config/compiler/sgi_mipspro.hpp +29 -0
  70. mqt/core/include/mqt-core/boost/config/compiler/sunpro_cc.hpp +225 -0
  71. mqt/core/include/mqt-core/boost/config/compiler/vacpp.hpp +189 -0
  72. mqt/core/include/mqt-core/boost/config/compiler/visualc.hpp +398 -0
  73. mqt/core/include/mqt-core/boost/config/compiler/xlcpp.hpp +303 -0
  74. mqt/core/include/mqt-core/boost/config/compiler/xlcpp_zos.hpp +174 -0
  75. mqt/core/include/mqt-core/boost/config/detail/cxx_composite.hpp +218 -0
  76. mqt/core/include/mqt-core/boost/config/detail/posix_features.hpp +95 -0
  77. mqt/core/include/mqt-core/boost/config/detail/select_compiler_config.hpp +157 -0
  78. mqt/core/include/mqt-core/boost/config/detail/select_platform_config.hpp +147 -0
  79. mqt/core/include/mqt-core/boost/config/detail/select_stdlib_config.hpp +121 -0
  80. mqt/core/include/mqt-core/boost/config/detail/suffix.hpp +1334 -0
  81. mqt/core/include/mqt-core/boost/config/header_deprecated.hpp +26 -0
  82. mqt/core/include/mqt-core/boost/config/helper_macros.hpp +37 -0
  83. mqt/core/include/mqt-core/boost/config/no_tr1/cmath.hpp +28 -0
  84. mqt/core/include/mqt-core/boost/config/no_tr1/complex.hpp +28 -0
  85. mqt/core/include/mqt-core/boost/config/no_tr1/functional.hpp +28 -0
  86. mqt/core/include/mqt-core/boost/config/no_tr1/memory.hpp +28 -0
  87. mqt/core/include/mqt-core/boost/config/no_tr1/utility.hpp +28 -0
  88. mqt/core/include/mqt-core/boost/config/platform/aix.hpp +33 -0
  89. mqt/core/include/mqt-core/boost/config/platform/amigaos.hpp +15 -0
  90. mqt/core/include/mqt-core/boost/config/platform/beos.hpp +26 -0
  91. mqt/core/include/mqt-core/boost/config/platform/bsd.hpp +83 -0
  92. mqt/core/include/mqt-core/boost/config/platform/cloudabi.hpp +18 -0
  93. mqt/core/include/mqt-core/boost/config/platform/cray.hpp +18 -0
  94. mqt/core/include/mqt-core/boost/config/platform/cygwin.hpp +71 -0
  95. mqt/core/include/mqt-core/boost/config/platform/haiku.hpp +31 -0
  96. mqt/core/include/mqt-core/boost/config/platform/hpux.hpp +87 -0
  97. mqt/core/include/mqt-core/boost/config/platform/irix.hpp +31 -0
  98. mqt/core/include/mqt-core/boost/config/platform/linux.hpp +106 -0
  99. mqt/core/include/mqt-core/boost/config/platform/macos.hpp +87 -0
  100. mqt/core/include/mqt-core/boost/config/platform/qnxnto.hpp +31 -0
  101. mqt/core/include/mqt-core/boost/config/platform/solaris.hpp +31 -0
  102. mqt/core/include/mqt-core/boost/config/platform/symbian.hpp +97 -0
  103. mqt/core/include/mqt-core/boost/config/platform/vms.hpp +25 -0
  104. mqt/core/include/mqt-core/boost/config/platform/vxworks.hpp +422 -0
  105. mqt/core/include/mqt-core/boost/config/platform/wasm.hpp +23 -0
  106. mqt/core/include/mqt-core/boost/config/platform/win32.hpp +90 -0
  107. mqt/core/include/mqt-core/boost/config/platform/zos.hpp +32 -0
  108. mqt/core/include/mqt-core/boost/config/pragma_message.hpp +31 -0
  109. mqt/core/include/mqt-core/boost/config/requires_threads.hpp +92 -0
  110. mqt/core/include/mqt-core/boost/config/stdlib/dinkumware.hpp +324 -0
  111. mqt/core/include/mqt-core/boost/config/stdlib/libcomo.hpp +93 -0
  112. mqt/core/include/mqt-core/boost/config/stdlib/libcpp.hpp +180 -0
  113. mqt/core/include/mqt-core/boost/config/stdlib/libstdcpp3.hpp +482 -0
  114. mqt/core/include/mqt-core/boost/config/stdlib/modena.hpp +79 -0
  115. mqt/core/include/mqt-core/boost/config/stdlib/msl.hpp +98 -0
  116. mqt/core/include/mqt-core/boost/config/stdlib/roguewave.hpp +208 -0
  117. mqt/core/include/mqt-core/boost/config/stdlib/sgi.hpp +168 -0
  118. mqt/core/include/mqt-core/boost/config/stdlib/stlport.hpp +258 -0
  119. mqt/core/include/mqt-core/boost/config/stdlib/vacpp.hpp +74 -0
  120. mqt/core/include/mqt-core/boost/config/stdlib/xlcpp_zos.hpp +61 -0
  121. mqt/core/include/mqt-core/boost/config/user.hpp +133 -0
  122. mqt/core/include/mqt-core/boost/config/warning_disable.hpp +47 -0
  123. mqt/core/include/mqt-core/boost/config/workaround.hpp +305 -0
  124. mqt/core/include/mqt-core/boost/config.hpp +67 -0
  125. mqt/core/include/mqt-core/boost/cstdint.hpp +556 -0
  126. mqt/core/include/mqt-core/boost/cxx11_char_types.hpp +70 -0
  127. mqt/core/include/mqt-core/boost/detail/workaround.hpp +10 -0
  128. mqt/core/include/mqt-core/boost/limits.hpp +146 -0
  129. mqt/core/include/mqt-core/boost/multiprecision/complex128.hpp +24 -0
  130. mqt/core/include/mqt-core/boost/multiprecision/complex_adaptor.hpp +1046 -0
  131. mqt/core/include/mqt-core/boost/multiprecision/concepts/mp_number_archetypes.hpp +257 -0
  132. mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float/io.hpp +698 -0
  133. mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float/transcendental.hpp +157 -0
  134. mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float.hpp +2297 -0
  135. mqt/core/include/mqt-core/boost/multiprecision/cpp_complex.hpp +12 -0
  136. mqt/core/include/mqt-core/boost/multiprecision/cpp_dec_float.hpp +3690 -0
  137. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/add.hpp +368 -0
  138. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/add_unsigned.hpp +387 -0
  139. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/bitwise.hpp +889 -0
  140. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/checked.hpp +178 -0
  141. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/comparison.hpp +374 -0
  142. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/cpp_int_config.hpp +161 -0
  143. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/divide.hpp +703 -0
  144. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/import_export.hpp +248 -0
  145. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/intel_intrinsics.hpp +138 -0
  146. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/limits.hpp +282 -0
  147. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/literals.hpp +295 -0
  148. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/misc.hpp +1457 -0
  149. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/multiply.hpp +848 -0
  150. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/serialize.hpp +211 -0
  151. mqt/core/include/mqt-core/boost/multiprecision/cpp_int/value_pack.hpp +42 -0
  152. mqt/core/include/mqt-core/boost/multiprecision/cpp_int.hpp +2360 -0
  153. mqt/core/include/mqt-core/boost/multiprecision/debug_adaptor.hpp +760 -0
  154. mqt/core/include/mqt-core/boost/multiprecision/detail/assert.hpp +29 -0
  155. mqt/core/include/mqt-core/boost/multiprecision/detail/atomic.hpp +62 -0
  156. mqt/core/include/mqt-core/boost/multiprecision/detail/bitscan.hpp +317 -0
  157. mqt/core/include/mqt-core/boost/multiprecision/detail/check_cpp11_config.hpp +64 -0
  158. mqt/core/include/mqt-core/boost/multiprecision/detail/constexpr.hpp +88 -0
  159. mqt/core/include/mqt-core/boost/multiprecision/detail/default_ops.hpp +4052 -0
  160. mqt/core/include/mqt-core/boost/multiprecision/detail/digits.hpp +49 -0
  161. mqt/core/include/mqt-core/boost/multiprecision/detail/dynamic_array.hpp +44 -0
  162. mqt/core/include/mqt-core/boost/multiprecision/detail/empty_value.hpp +87 -0
  163. mqt/core/include/mqt-core/boost/multiprecision/detail/endian.hpp +35 -0
  164. mqt/core/include/mqt-core/boost/multiprecision/detail/et_ops.hpp +1831 -0
  165. mqt/core/include/mqt-core/boost/multiprecision/detail/float128_functions.hpp +95 -0
  166. mqt/core/include/mqt-core/boost/multiprecision/detail/float_string_cvt.hpp +333 -0
  167. mqt/core/include/mqt-core/boost/multiprecision/detail/fpclassify.hpp +101 -0
  168. mqt/core/include/mqt-core/boost/multiprecision/detail/functions/constants.hpp +288 -0
  169. mqt/core/include/mqt-core/boost/multiprecision/detail/functions/pow.hpp +905 -0
  170. mqt/core/include/mqt-core/boost/multiprecision/detail/functions/trig.hpp +1058 -0
  171. mqt/core/include/mqt-core/boost/multiprecision/detail/functions/trunc.hpp +82 -0
  172. mqt/core/include/mqt-core/boost/multiprecision/detail/generic_interconvert.hpp +687 -0
  173. mqt/core/include/mqt-core/boost/multiprecision/detail/hash.hpp +56 -0
  174. mqt/core/include/mqt-core/boost/multiprecision/detail/integer_ops.hpp +474 -0
  175. mqt/core/include/mqt-core/boost/multiprecision/detail/itos.hpp +39 -0
  176. mqt/core/include/mqt-core/boost/multiprecision/detail/min_max.hpp +106 -0
  177. mqt/core/include/mqt-core/boost/multiprecision/detail/no_et_ops.hpp +661 -0
  178. mqt/core/include/mqt-core/boost/multiprecision/detail/no_exceptions_support.hpp +55 -0
  179. mqt/core/include/mqt-core/boost/multiprecision/detail/number_base.hpp +1656 -0
  180. mqt/core/include/mqt-core/boost/multiprecision/detail/number_compare.hpp +848 -0
  181. mqt/core/include/mqt-core/boost/multiprecision/detail/precision.hpp +313 -0
  182. mqt/core/include/mqt-core/boost/multiprecision/detail/rebind.hpp +19 -0
  183. mqt/core/include/mqt-core/boost/multiprecision/detail/standalone_config.hpp +148 -0
  184. mqt/core/include/mqt-core/boost/multiprecision/detail/static_array.hpp +42 -0
  185. mqt/core/include/mqt-core/boost/multiprecision/detail/string_helpers.hpp +48 -0
  186. mqt/core/include/mqt-core/boost/multiprecision/detail/tables.hpp +80 -0
  187. mqt/core/include/mqt-core/boost/multiprecision/detail/ublas_interop.hpp +75 -0
  188. mqt/core/include/mqt-core/boost/multiprecision/detail/uniform_int_distribution.hpp +212 -0
  189. mqt/core/include/mqt-core/boost/multiprecision/detail/utype_helper.hpp +374 -0
  190. mqt/core/include/mqt-core/boost/multiprecision/eigen.hpp +248 -0
  191. mqt/core/include/mqt-core/boost/multiprecision/float128.hpp +920 -0
  192. mqt/core/include/mqt-core/boost/multiprecision/fwd.hpp +268 -0
  193. mqt/core/include/mqt-core/boost/multiprecision/gmp.hpp +4060 -0
  194. mqt/core/include/mqt-core/boost/multiprecision/integer.hpp +363 -0
  195. mqt/core/include/mqt-core/boost/multiprecision/logged_adaptor.hpp +834 -0
  196. mqt/core/include/mqt-core/boost/multiprecision/miller_rabin.hpp +221 -0
  197. mqt/core/include/mqt-core/boost/multiprecision/mpc.hpp +1721 -0
  198. mqt/core/include/mqt-core/boost/multiprecision/mpfi.hpp +2559 -0
  199. mqt/core/include/mqt-core/boost/multiprecision/mpfr.hpp +3644 -0
  200. mqt/core/include/mqt-core/boost/multiprecision/number.hpp +2500 -0
  201. mqt/core/include/mqt-core/boost/multiprecision/random.hpp +23 -0
  202. mqt/core/include/mqt-core/boost/multiprecision/rational_adaptor.hpp +1289 -0
  203. mqt/core/include/mqt-core/boost/multiprecision/tommath.hpp +1034 -0
  204. mqt/core/include/mqt-core/boost/multiprecision/traits/explicit_conversion.hpp +67 -0
  205. mqt/core/include/mqt-core/boost/multiprecision/traits/extract_exponent_type.hpp +28 -0
  206. mqt/core/include/mqt-core/boost/multiprecision/traits/is_backend.hpp +91 -0
  207. mqt/core/include/mqt-core/boost/multiprecision/traits/is_byte_container.hpp +51 -0
  208. mqt/core/include/mqt-core/boost/multiprecision/traits/is_complex.hpp +22 -0
  209. mqt/core/include/mqt-core/boost/multiprecision/traits/is_convertible_arithmetic.hpp +51 -0
  210. mqt/core/include/mqt-core/boost/multiprecision/traits/is_restricted_conversion.hpp +47 -0
  211. mqt/core/include/mqt-core/boost/multiprecision/traits/is_variable_precision.hpp +25 -0
  212. mqt/core/include/mqt-core/boost/multiprecision/traits/max_digits10.hpp +79 -0
  213. mqt/core/include/mqt-core/boost/multiprecision/traits/std_integer_traits.hpp +90 -0
  214. mqt/core/include/mqt-core/boost/multiprecision/traits/transcendental_reduction_type.hpp +21 -0
  215. mqt/core/include/mqt-core/boost/version.hpp +32 -0
  216. mqt/core/include/mqt-core/circuit_optimizer/CircuitOptimizer.hpp +119 -0
  217. mqt/core/include/mqt-core/circuit_optimizer/mqt_core_circuit_optimizer_export.h +43 -0
  218. mqt/core/include/mqt-core/datastructures/DirectedAcyclicGraph.hpp +117 -0
  219. mqt/core/include/mqt-core/datastructures/DirectedGraph.hpp +158 -0
  220. mqt/core/include/mqt-core/datastructures/DisjointSet.hpp +50 -0
  221. mqt/core/include/mqt-core/datastructures/Layer.hpp +172 -0
  222. mqt/core/include/mqt-core/datastructures/SymmetricMatrix.hpp +57 -0
  223. mqt/core/include/mqt-core/datastructures/UndirectedGraph.hpp +227 -0
  224. mqt/core/include/mqt-core/datastructures/mqt_core_ds_export.h +43 -0
  225. mqt/core/include/mqt-core/dd/Approximation.hpp +45 -0
  226. mqt/core/include/mqt-core/dd/CachedEdge.hpp +174 -0
  227. mqt/core/include/mqt-core/dd/Complex.hpp +165 -0
  228. mqt/core/include/mqt-core/dd/ComplexNumbers.hpp +150 -0
  229. mqt/core/include/mqt-core/dd/ComplexValue.hpp +184 -0
  230. mqt/core/include/mqt-core/dd/ComputeTable.hpp +183 -0
  231. mqt/core/include/mqt-core/dd/DDDefinitions.hpp +139 -0
  232. mqt/core/include/mqt-core/dd/DDpackageConfig.hpp +104 -0
  233. mqt/core/include/mqt-core/dd/DensityNoiseTable.hpp +114 -0
  234. mqt/core/include/mqt-core/dd/Edge.hpp +416 -0
  235. mqt/core/include/mqt-core/dd/Export.hpp +438 -0
  236. mqt/core/include/mqt-core/dd/FunctionalityConstruction.hpp +75 -0
  237. mqt/core/include/mqt-core/dd/GateMatrixDefinitions.hpp +43 -0
  238. mqt/core/include/mqt-core/dd/LinkedListBase.hpp +45 -0
  239. mqt/core/include/mqt-core/dd/MemoryManager.hpp +193 -0
  240. mqt/core/include/mqt-core/dd/Node.hpp +223 -0
  241. mqt/core/include/mqt-core/dd/NoiseFunctionality.hpp +144 -0
  242. mqt/core/include/mqt-core/dd/Operations.hpp +306 -0
  243. mqt/core/include/mqt-core/dd/Package.hpp +2036 -0
  244. mqt/core/include/mqt-core/dd/Package_fwd.hpp +22 -0
  245. mqt/core/include/mqt-core/dd/RealNumber.hpp +255 -0
  246. mqt/core/include/mqt-core/dd/RealNumberUniqueTable.hpp +217 -0
  247. mqt/core/include/mqt-core/dd/Simulation.hpp +98 -0
  248. mqt/core/include/mqt-core/dd/StateGeneration.hpp +143 -0
  249. mqt/core/include/mqt-core/dd/StochasticNoiseOperationTable.hpp +88 -0
  250. mqt/core/include/mqt-core/dd/UnaryComputeTable.hpp +121 -0
  251. mqt/core/include/mqt-core/dd/UniqueTable.hpp +243 -0
  252. mqt/core/include/mqt-core/dd/mqt_core_dd_export.h +43 -0
  253. mqt/core/include/mqt-core/dd/statistics/MemoryManagerStatistics.hpp +84 -0
  254. mqt/core/include/mqt-core/dd/statistics/PackageStatistics.hpp +55 -0
  255. mqt/core/include/mqt-core/dd/statistics/Statistics.hpp +48 -0
  256. mqt/core/include/mqt-core/dd/statistics/TableStatistics.hpp +79 -0
  257. mqt/core/include/mqt-core/dd/statistics/UniqueTableStatistics.hpp +31 -0
  258. mqt/core/include/mqt-core/fomac/FoMaC.hpp +568 -0
  259. mqt/core/include/mqt-core/ir/Definitions.hpp +108 -0
  260. mqt/core/include/mqt-core/ir/Permutation.hpp +213 -0
  261. mqt/core/include/mqt-core/ir/QuantumComputation.hpp +596 -0
  262. mqt/core/include/mqt-core/ir/Register.hpp +125 -0
  263. mqt/core/include/mqt-core/ir/mqt_core_ir_export.h +43 -0
  264. mqt/core/include/mqt-core/ir/operations/AodOperation.hpp +92 -0
  265. mqt/core/include/mqt-core/ir/operations/CompoundOperation.hpp +212 -0
  266. mqt/core/include/mqt-core/ir/operations/Control.hpp +142 -0
  267. mqt/core/include/mqt-core/ir/operations/Expression.hpp +847 -0
  268. mqt/core/include/mqt-core/ir/operations/IfElseOperation.hpp +169 -0
  269. mqt/core/include/mqt-core/ir/operations/NonUnitaryOperation.hpp +118 -0
  270. mqt/core/include/mqt-core/ir/operations/OpType.hpp +120 -0
  271. mqt/core/include/mqt-core/ir/operations/OpType.inc +76 -0
  272. mqt/core/include/mqt-core/ir/operations/Operation.hpp +247 -0
  273. mqt/core/include/mqt-core/ir/operations/StandardOperation.hpp +140 -0
  274. mqt/core/include/mqt-core/ir/operations/SymbolicOperation.hpp +144 -0
  275. mqt/core/include/mqt-core/mqt_na_qdmi/device.h +602 -0
  276. mqt/core/include/mqt-core/mqt_na_qdmi/types.h +78 -0
  277. mqt/core/include/mqt-core/na/NAComputation.hpp +185 -0
  278. mqt/core/include/mqt-core/na/device/Device.hpp +410 -0
  279. mqt/core/include/mqt-core/na/device/DeviceMemberInitializers.hpp +724 -0
  280. mqt/core/include/mqt-core/na/device/Generator.hpp +447 -0
  281. mqt/core/include/mqt-core/na/entities/Atom.hpp +62 -0
  282. mqt/core/include/mqt-core/na/entities/Location.hpp +154 -0
  283. mqt/core/include/mqt-core/na/entities/Zone.hpp +95 -0
  284. mqt/core/include/mqt-core/na/fomac/Device.hpp +169 -0
  285. mqt/core/include/mqt-core/na/mqt_core_na_export.h +43 -0
  286. mqt/core/include/mqt-core/na/operations/GlobalCZOp.hpp +38 -0
  287. mqt/core/include/mqt-core/na/operations/GlobalOp.hpp +58 -0
  288. mqt/core/include/mqt-core/na/operations/GlobalRYOp.hpp +42 -0
  289. mqt/core/include/mqt-core/na/operations/LoadOp.hpp +89 -0
  290. mqt/core/include/mqt-core/na/operations/LocalOp.hpp +56 -0
  291. mqt/core/include/mqt-core/na/operations/LocalRZOp.hpp +42 -0
  292. mqt/core/include/mqt-core/na/operations/LocalUOp.hpp +49 -0
  293. mqt/core/include/mqt-core/na/operations/MoveOp.hpp +66 -0
  294. mqt/core/include/mqt-core/na/operations/Op.hpp +62 -0
  295. mqt/core/include/mqt-core/na/operations/ShuttlingOp.hpp +51 -0
  296. mqt/core/include/mqt-core/na/operations/StoreOp.hpp +87 -0
  297. mqt/core/include/mqt-core/qasm3/Exception.hpp +85 -0
  298. mqt/core/include/mqt-core/qasm3/Gate.hpp +65 -0
  299. mqt/core/include/mqt-core/qasm3/Importer.hpp +192 -0
  300. mqt/core/include/mqt-core/qasm3/InstVisitor.hpp +145 -0
  301. mqt/core/include/mqt-core/qasm3/NestedEnvironment.hpp +41 -0
  302. mqt/core/include/mqt-core/qasm3/Parser.hpp +170 -0
  303. mqt/core/include/mqt-core/qasm3/Scanner.hpp +73 -0
  304. mqt/core/include/mqt-core/qasm3/Statement.hpp +486 -0
  305. mqt/core/include/mqt-core/qasm3/Statement_fwd.hpp +39 -0
  306. mqt/core/include/mqt-core/qasm3/StdGates.hpp +232 -0
  307. mqt/core/include/mqt-core/qasm3/Token.hpp +198 -0
  308. mqt/core/include/mqt-core/qasm3/Types.hpp +238 -0
  309. mqt/core/include/mqt-core/qasm3/Types_fwd.hpp +22 -0
  310. mqt/core/include/mqt-core/qasm3/mqt_core_qasm_export.h +43 -0
  311. mqt/core/include/mqt-core/qasm3/passes/CompilerPass.hpp +22 -0
  312. mqt/core/include/mqt-core/qasm3/passes/ConstEvalPass.hpp +102 -0
  313. mqt/core/include/mqt-core/qasm3/passes/TypeCheckPass.hpp +124 -0
  314. mqt/core/include/mqt-core/qdmi/Driver.hpp +431 -0
  315. mqt/core/include/mqt-core/zx/FunctionalityConstruction.hpp +125 -0
  316. mqt/core/include/mqt-core/zx/Rational.hpp +318 -0
  317. mqt/core/include/mqt-core/zx/Rules.hpp +132 -0
  318. mqt/core/include/mqt-core/zx/Simplify.hpp +182 -0
  319. mqt/core/include/mqt-core/zx/Utils.hpp +212 -0
  320. mqt/core/include/mqt-core/zx/ZXDefinitions.hpp +93 -0
  321. mqt/core/include/mqt-core/zx/ZXDiagram.hpp +480 -0
  322. mqt/core/include/mqt-core/zx/mqt_core_zx_export.h +43 -0
  323. mqt/core/include/nlohmann/adl_serializer.hpp +55 -0
  324. mqt/core/include/nlohmann/byte_container_with_subtype.hpp +103 -0
  325. mqt/core/include/nlohmann/detail/abi_macros.hpp +111 -0
  326. mqt/core/include/nlohmann/detail/conversions/from_json.hpp +577 -0
  327. mqt/core/include/nlohmann/detail/conversions/to_chars.hpp +1118 -0
  328. mqt/core/include/nlohmann/detail/conversions/to_json.hpp +479 -0
  329. mqt/core/include/nlohmann/detail/exceptions.hpp +291 -0
  330. mqt/core/include/nlohmann/detail/hash.hpp +129 -0
  331. mqt/core/include/nlohmann/detail/input/binary_reader.hpp +3068 -0
  332. mqt/core/include/nlohmann/detail/input/input_adapters.hpp +549 -0
  333. mqt/core/include/nlohmann/detail/input/json_sax.hpp +986 -0
  334. mqt/core/include/nlohmann/detail/input/lexer.hpp +1643 -0
  335. mqt/core/include/nlohmann/detail/input/parser.hpp +519 -0
  336. mqt/core/include/nlohmann/detail/input/position_t.hpp +37 -0
  337. mqt/core/include/nlohmann/detail/iterators/internal_iterator.hpp +35 -0
  338. mqt/core/include/nlohmann/detail/iterators/iter_impl.hpp +760 -0
  339. mqt/core/include/nlohmann/detail/iterators/iteration_proxy.hpp +235 -0
  340. mqt/core/include/nlohmann/detail/iterators/iterator_traits.hpp +61 -0
  341. mqt/core/include/nlohmann/detail/iterators/json_reverse_iterator.hpp +130 -0
  342. mqt/core/include/nlohmann/detail/iterators/primitive_iterator.hpp +132 -0
  343. mqt/core/include/nlohmann/detail/json_custom_base_class.hpp +39 -0
  344. mqt/core/include/nlohmann/detail/json_pointer.hpp +988 -0
  345. mqt/core/include/nlohmann/detail/json_ref.hpp +78 -0
  346. mqt/core/include/nlohmann/detail/macro_scope.hpp +595 -0
  347. mqt/core/include/nlohmann/detail/macro_unscope.hpp +46 -0
  348. mqt/core/include/nlohmann/detail/meta/call_std/begin.hpp +17 -0
  349. mqt/core/include/nlohmann/detail/meta/call_std/end.hpp +17 -0
  350. mqt/core/include/nlohmann/detail/meta/cpp_future.hpp +171 -0
  351. mqt/core/include/nlohmann/detail/meta/detected.hpp +70 -0
  352. mqt/core/include/nlohmann/detail/meta/identity_tag.hpp +21 -0
  353. mqt/core/include/nlohmann/detail/meta/is_sax.hpp +159 -0
  354. mqt/core/include/nlohmann/detail/meta/std_fs.hpp +29 -0
  355. mqt/core/include/nlohmann/detail/meta/type_traits.hpp +795 -0
  356. mqt/core/include/nlohmann/detail/meta/void_t.hpp +24 -0
  357. mqt/core/include/nlohmann/detail/output/binary_writer.hpp +1850 -0
  358. mqt/core/include/nlohmann/detail/output/output_adapters.hpp +147 -0
  359. mqt/core/include/nlohmann/detail/output/serializer.hpp +988 -0
  360. mqt/core/include/nlohmann/detail/string_concat.hpp +146 -0
  361. mqt/core/include/nlohmann/detail/string_escape.hpp +72 -0
  362. mqt/core/include/nlohmann/detail/string_utils.hpp +37 -0
  363. mqt/core/include/nlohmann/detail/value_t.hpp +118 -0
  364. mqt/core/include/nlohmann/json.hpp +5306 -0
  365. mqt/core/include/nlohmann/json_fwd.hpp +75 -0
  366. mqt/core/include/nlohmann/ordered_map.hpp +359 -0
  367. mqt/core/include/nlohmann/thirdparty/hedley/hedley.hpp +2045 -0
  368. mqt/core/include/nlohmann/thirdparty/hedley/hedley_undef.hpp +158 -0
  369. mqt/core/include/qdmi/qdmi/client.h +990 -0
  370. mqt/core/include/qdmi/qdmi/constants.h +1139 -0
  371. mqt/core/include/qdmi/qdmi/device.h +602 -0
  372. mqt/core/include/qdmi/qdmi/types.h +78 -0
  373. mqt/core/include/spdlog/async.h +99 -0
  374. mqt/core/include/spdlog/async_logger-inl.h +84 -0
  375. mqt/core/include/spdlog/async_logger.h +74 -0
  376. mqt/core/include/spdlog/cfg/argv.h +40 -0
  377. mqt/core/include/spdlog/cfg/env.h +36 -0
  378. mqt/core/include/spdlog/cfg/helpers-inl.h +107 -0
  379. mqt/core/include/spdlog/cfg/helpers.h +29 -0
  380. mqt/core/include/spdlog/common-inl.h +68 -0
  381. mqt/core/include/spdlog/common.h +406 -0
  382. mqt/core/include/spdlog/details/backtracer-inl.h +63 -0
  383. mqt/core/include/spdlog/details/backtracer.h +45 -0
  384. mqt/core/include/spdlog/details/circular_q.h +115 -0
  385. mqt/core/include/spdlog/details/console_globals.h +28 -0
  386. mqt/core/include/spdlog/details/file_helper-inl.h +153 -0
  387. mqt/core/include/spdlog/details/file_helper.h +61 -0
  388. mqt/core/include/spdlog/details/fmt_helper.h +141 -0
  389. mqt/core/include/spdlog/details/log_msg-inl.h +44 -0
  390. mqt/core/include/spdlog/details/log_msg.h +40 -0
  391. mqt/core/include/spdlog/details/log_msg_buffer-inl.h +54 -0
  392. mqt/core/include/spdlog/details/log_msg_buffer.h +32 -0
  393. mqt/core/include/spdlog/details/mpmc_blocking_q.h +177 -0
  394. mqt/core/include/spdlog/details/null_mutex.h +35 -0
  395. mqt/core/include/spdlog/details/os-inl.h +606 -0
  396. mqt/core/include/spdlog/details/os.h +127 -0
  397. mqt/core/include/spdlog/details/periodic_worker-inl.h +26 -0
  398. mqt/core/include/spdlog/details/periodic_worker.h +58 -0
  399. mqt/core/include/spdlog/details/registry-inl.h +270 -0
  400. mqt/core/include/spdlog/details/registry.h +131 -0
  401. mqt/core/include/spdlog/details/synchronous_factory.h +22 -0
  402. mqt/core/include/spdlog/details/tcp_client-windows.h +135 -0
  403. mqt/core/include/spdlog/details/tcp_client.h +127 -0
  404. mqt/core/include/spdlog/details/thread_pool-inl.h +126 -0
  405. mqt/core/include/spdlog/details/thread_pool.h +117 -0
  406. mqt/core/include/spdlog/details/udp_client-windows.h +98 -0
  407. mqt/core/include/spdlog/details/udp_client.h +81 -0
  408. mqt/core/include/spdlog/details/windows_include.h +11 -0
  409. mqt/core/include/spdlog/fmt/bin_to_hex.h +224 -0
  410. mqt/core/include/spdlog/fmt/bundled/args.h +220 -0
  411. mqt/core/include/spdlog/fmt/bundled/base.h +2989 -0
  412. mqt/core/include/spdlog/fmt/bundled/chrono.h +2330 -0
  413. mqt/core/include/spdlog/fmt/bundled/color.h +637 -0
  414. mqt/core/include/spdlog/fmt/bundled/compile.h +539 -0
  415. mqt/core/include/spdlog/fmt/bundled/core.h +5 -0
  416. mqt/core/include/spdlog/fmt/bundled/fmt.license.rst +27 -0
  417. mqt/core/include/spdlog/fmt/bundled/format-inl.h +1948 -0
  418. mqt/core/include/spdlog/fmt/bundled/format.h +4244 -0
  419. mqt/core/include/spdlog/fmt/bundled/os.h +427 -0
  420. mqt/core/include/spdlog/fmt/bundled/ostream.h +167 -0
  421. mqt/core/include/spdlog/fmt/bundled/printf.h +633 -0
  422. mqt/core/include/spdlog/fmt/bundled/ranges.h +850 -0
  423. mqt/core/include/spdlog/fmt/bundled/std.h +728 -0
  424. mqt/core/include/spdlog/fmt/bundled/xchar.h +369 -0
  425. mqt/core/include/spdlog/fmt/chrono.h +23 -0
  426. mqt/core/include/spdlog/fmt/compile.h +23 -0
  427. mqt/core/include/spdlog/fmt/fmt.h +30 -0
  428. mqt/core/include/spdlog/fmt/ostr.h +23 -0
  429. mqt/core/include/spdlog/fmt/ranges.h +23 -0
  430. mqt/core/include/spdlog/fmt/std.h +24 -0
  431. mqt/core/include/spdlog/fmt/xchar.h +23 -0
  432. mqt/core/include/spdlog/formatter.h +17 -0
  433. mqt/core/include/spdlog/fwd.h +18 -0
  434. mqt/core/include/spdlog/logger-inl.h +198 -0
  435. mqt/core/include/spdlog/logger.h +379 -0
  436. mqt/core/include/spdlog/mdc.h +52 -0
  437. mqt/core/include/spdlog/pattern_formatter-inl.h +1340 -0
  438. mqt/core/include/spdlog/pattern_formatter.h +118 -0
  439. mqt/core/include/spdlog/sinks/android_sink.h +137 -0
  440. mqt/core/include/spdlog/sinks/ansicolor_sink-inl.h +142 -0
  441. mqt/core/include/spdlog/sinks/ansicolor_sink.h +116 -0
  442. mqt/core/include/spdlog/sinks/base_sink-inl.h +59 -0
  443. mqt/core/include/spdlog/sinks/base_sink.h +51 -0
  444. mqt/core/include/spdlog/sinks/basic_file_sink-inl.h +48 -0
  445. mqt/core/include/spdlog/sinks/basic_file_sink.h +66 -0
  446. mqt/core/include/spdlog/sinks/callback_sink.h +56 -0
  447. mqt/core/include/spdlog/sinks/daily_file_sink.h +254 -0
  448. mqt/core/include/spdlog/sinks/dist_sink.h +81 -0
  449. mqt/core/include/spdlog/sinks/dup_filter_sink.h +91 -0
  450. mqt/core/include/spdlog/sinks/hourly_file_sink.h +193 -0
  451. mqt/core/include/spdlog/sinks/kafka_sink.h +119 -0
  452. mqt/core/include/spdlog/sinks/mongo_sink.h +108 -0
  453. mqt/core/include/spdlog/sinks/msvc_sink.h +68 -0
  454. mqt/core/include/spdlog/sinks/null_sink.h +41 -0
  455. mqt/core/include/spdlog/sinks/ostream_sink.h +43 -0
  456. mqt/core/include/spdlog/sinks/qt_sinks.h +304 -0
  457. mqt/core/include/spdlog/sinks/ringbuffer_sink.h +67 -0
  458. mqt/core/include/spdlog/sinks/rotating_file_sink-inl.h +179 -0
  459. mqt/core/include/spdlog/sinks/rotating_file_sink.h +93 -0
  460. mqt/core/include/spdlog/sinks/sink-inl.h +22 -0
  461. mqt/core/include/spdlog/sinks/sink.h +34 -0
  462. mqt/core/include/spdlog/sinks/stdout_color_sinks-inl.h +38 -0
  463. mqt/core/include/spdlog/sinks/stdout_color_sinks.h +49 -0
  464. mqt/core/include/spdlog/sinks/stdout_sinks-inl.h +127 -0
  465. mqt/core/include/spdlog/sinks/stdout_sinks.h +84 -0
  466. mqt/core/include/spdlog/sinks/syslog_sink.h +104 -0
  467. mqt/core/include/spdlog/sinks/systemd_sink.h +121 -0
  468. mqt/core/include/spdlog/sinks/tcp_sink.h +75 -0
  469. mqt/core/include/spdlog/sinks/udp_sink.h +69 -0
  470. mqt/core/include/spdlog/sinks/win_eventlog_sink.h +260 -0
  471. mqt/core/include/spdlog/sinks/wincolor_sink-inl.h +172 -0
  472. mqt/core/include/spdlog/sinks/wincolor_sink.h +82 -0
  473. mqt/core/include/spdlog/spdlog-inl.h +96 -0
  474. mqt/core/include/spdlog/spdlog.h +357 -0
  475. mqt/core/include/spdlog/stopwatch.h +66 -0
  476. mqt/core/include/spdlog/tweakme.h +148 -0
  477. mqt/core/include/spdlog/version.h +11 -0
  478. mqt/core/ir/__init__.pyi +2078 -0
  479. mqt/core/ir/operations.pyi +1011 -0
  480. mqt/core/ir/registers.pyi +91 -0
  481. mqt/core/ir/symbolic.pyi +177 -0
  482. mqt/core/ir.cp313t-win_amd64.pyd +0 -0
  483. mqt/core/lib/mqt-core-algorithms.lib +0 -0
  484. mqt/core/lib/mqt-core-circuit-optimizer.lib +0 -0
  485. mqt/core/lib/mqt-core-dd.lib +0 -0
  486. mqt/core/lib/mqt-core-ds.lib +0 -0
  487. mqt/core/lib/mqt-core-fomac.lib +0 -0
  488. mqt/core/lib/mqt-core-ir.lib +0 -0
  489. mqt/core/lib/mqt-core-na-fomac.lib +0 -0
  490. mqt/core/lib/mqt-core-na.lib +0 -0
  491. mqt/core/lib/mqt-core-qasm.lib +0 -0
  492. mqt/core/lib/mqt-core-qdmi-driver.lib +0 -0
  493. mqt/core/lib/mqt-core-qdmi-na-device-gen.lib +0 -0
  494. mqt/core/lib/mqt-core-qdmi-na-device.lib +0 -0
  495. mqt/core/lib/mqt-core-zx.lib +0 -0
  496. mqt/core/lib/pkgconfig/spdlog.pc +13 -0
  497. mqt/core/lib/spdlog.lib +0 -0
  498. mqt/core/na/__init__.py +12 -0
  499. mqt/core/na/fomac.cp313t-win_amd64.pyd +0 -0
  500. mqt/core/na/fomac.pyi +117 -0
  501. mqt/core/nlohmann_json.natvis +278 -0
  502. mqt/core/plugins/__init__.py +9 -0
  503. mqt/core/plugins/qiskit/__init__.py +19 -0
  504. mqt/core/plugins/qiskit/mqt_to_qiskit.py +420 -0
  505. mqt/core/plugins/qiskit/qiskit_to_mqt.py +562 -0
  506. mqt/core/py.typed +2 -0
  507. mqt/core/share/cmake/mqt-core/AddMQTPythonBinding.cmake +55 -0
  508. mqt/core/share/cmake/mqt-core/Cache.cmake +33 -0
  509. mqt/core/share/cmake/mqt-core/FindGMP.cmake +103 -0
  510. mqt/core/share/cmake/mqt-core/PackageAddTest.cmake +46 -0
  511. mqt/core/share/cmake/mqt-core/PreventInSourceBuilds.cmake +25 -0
  512. mqt/core/share/cmake/mqt-core/StandardProjectSettings.cmake +87 -0
  513. mqt/core/share/cmake/mqt-core/mqt-core-config-version.cmake +85 -0
  514. mqt/core/share/cmake/mqt-core/mqt-core-config.cmake +52 -0
  515. mqt/core/share/cmake/mqt-core/mqt-core-targets-release.cmake +141 -0
  516. mqt/core/share/cmake/mqt-core/mqt-core-targets.cmake +445 -0
  517. mqt/core/share/cmake/nlohmann_json/nlohmann_jsonConfig.cmake +15 -0
  518. mqt/core/share/cmake/nlohmann_json/nlohmann_jsonConfigVersion.cmake +20 -0
  519. mqt/core/share/cmake/nlohmann_json/nlohmann_jsonTargets.cmake +110 -0
  520. mqt/core/share/cmake/qdmi/Cache.cmake +44 -0
  521. mqt/core/share/cmake/qdmi/PrefixHandling.cmake +78 -0
  522. mqt/core/share/cmake/qdmi/prefix_defs.txt +26 -0
  523. mqt/core/share/cmake/qdmi/qdmi-config-version.cmake +85 -0
  524. mqt/core/share/cmake/qdmi/qdmi-config.cmake +42 -0
  525. mqt/core/share/cmake/qdmi/qdmi-targets.cmake +129 -0
  526. mqt/core/share/cmake/spdlog/spdlogConfig.cmake +44 -0
  527. mqt/core/share/cmake/spdlog/spdlogConfigTargets-release.cmake +19 -0
  528. mqt/core/share/cmake/spdlog/spdlogConfigTargets.cmake +121 -0
  529. mqt/core/share/cmake/spdlog/spdlogConfigVersion.cmake +65 -0
  530. mqt/core/share/pkgconfig/nlohmann_json.pc +7 -0
  531. mqt_core-3.3.2.dist-info/DELVEWHEEL +2 -0
  532. mqt_core-3.3.2.dist-info/METADATA +210 -0
  533. mqt_core-3.3.2.dist-info/RECORD +537 -0
  534. mqt_core-3.3.2.dist-info/WHEEL +5 -0
  535. mqt_core-3.3.2.dist-info/entry_points.txt +4 -0
  536. mqt_core-3.3.2.dist-info/licenses/LICENSE.md +22 -0
  537. mqt_core.libs/msvcp140.dll +0 -0
@@ -0,0 +1,2297 @@
1
+ ////////////////////////////////////////////////////////////////
2
+ // Copyright 2013 - 2022 John Maddock.
3
+ // Copyright 2022 Christopher Kormanyos.
4
+ // Distributed under the Boost Software License,
5
+ // Version 1.0. (See accompanying file LICENSE_1_0.txt
6
+ // or copy at https://www.boost.org/LICENSE_1_0.txt)
7
+
8
+ #ifndef BOOST_MP_CPP_BIN_FLOAT_HPP
9
+ #define BOOST_MP_CPP_BIN_FLOAT_HPP
10
+
11
+ #include <cmath>
12
+ #include <cstdint>
13
+ #include <limits>
14
+ #include <type_traits>
15
+ #include <boost/multiprecision/cpp_int.hpp>
16
+ #include <boost/multiprecision/integer.hpp>
17
+ #include <boost/multiprecision/detail/standalone_config.hpp>
18
+ #include <boost/multiprecision/detail/fpclassify.hpp>
19
+ #include <boost/multiprecision/detail/float_string_cvt.hpp>
20
+ #include <boost/multiprecision/traits/max_digits10.hpp>
21
+ #include <boost/multiprecision/detail/hash.hpp>
22
+ #include <boost/multiprecision/detail/no_exceptions_support.hpp>
23
+ #include <boost/multiprecision/detail/assert.hpp>
24
+ #include <boost/multiprecision/detail/float128_functions.hpp>
25
+ #include <boost/multiprecision/detail/functions/trunc.hpp>
26
+
27
+ //
28
+ // Some includes we need from Boost.Math, since we rely on that library to provide these functions:
29
+ //
30
+ #ifdef BOOST_MP_MATH_AVAILABLE
31
+ #include <boost/math/special_functions/asinh.hpp>
32
+ #include <boost/math/special_functions/acosh.hpp>
33
+ #include <boost/math/special_functions/atanh.hpp>
34
+ #include <boost/math/special_functions/cbrt.hpp>
35
+ #include <boost/math/special_functions/expm1.hpp>
36
+ #include <boost/math/special_functions/gamma.hpp>
37
+ #endif
38
+
39
+ #ifdef BOOST_HAS_FLOAT128
40
+ # if __has_include(<quadmath.h>)
41
+ # include <quadmath.h>
42
+ # define BOOST_MP_HAS_FLOAT128_SUPPORT
43
+ # endif
44
+ #endif
45
+
46
+ namespace boost {
47
+ namespace multiprecision {
48
+ namespace backends {
49
+
50
+ #ifdef BOOST_MSVC
51
+ #pragma warning(push)
52
+ #pragma warning(disable : 4522 6326) // multiple assignment operators specified, comparison of two constants
53
+ #endif
54
+
55
+ namespace detail {
56
+
57
+ template <class U>
58
+ inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<U>::value, bool>::type is_negative(U) { return false; }
59
+ template <class S>
60
+ inline typename std::enable_if< !boost::multiprecision::detail::is_unsigned<S>::value, bool>::type is_negative(S s) { return s < 0; }
61
+
62
+ template <class Float, std::ptrdiff_t, bool = number_category<Float>::value == number_kind_floating_point>
63
+ struct is_cpp_bin_float_implicitly_constructible_from_type
64
+ {
65
+ static constexpr bool value = false;
66
+ };
67
+
68
+ template <class Float, std::ptrdiff_t bit_count>
69
+ struct is_cpp_bin_float_implicitly_constructible_from_type<Float, bit_count, true>
70
+ {
71
+ static constexpr bool value = (std::numeric_limits<Float>::digits <= static_cast<int>(bit_count)) && (std::numeric_limits<Float>::radix == 2) && std::numeric_limits<Float>::is_specialized
72
+ #ifdef BOOST_MP_HAS_FLOAT128_SUPPORT
73
+ && !std::is_same<Float, float128_type>::value
74
+ #endif
75
+ && (std::is_floating_point<Float>::value || is_number<Float>::value);
76
+ };
77
+
78
+ template <class Float, std::ptrdiff_t, bool = number_category<Float>::value == number_kind_floating_point>
79
+ struct is_cpp_bin_float_explicitly_constructible_from_type
80
+ {
81
+ static constexpr bool value = false;
82
+ };
83
+
84
+ template <class Float, std::ptrdiff_t bit_count>
85
+ struct is_cpp_bin_float_explicitly_constructible_from_type<Float, bit_count, true>
86
+ {
87
+ static constexpr bool value = (std::numeric_limits<Float>::digits > static_cast<int>(bit_count)) && (std::numeric_limits<Float>::radix == 2) && std::numeric_limits<Float>::is_specialized
88
+ #ifdef BOOST_MP_HAS_FLOAT128_SUPPORT
89
+ && !std::is_same<Float, float128_type>::value
90
+ #endif
91
+ ;
92
+ };
93
+
94
+ } // namespace detail
95
+
96
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinExponent, Exponent MaxExponent>
97
+ class cpp_bin_float
98
+ {
99
+ public:
100
+ static constexpr unsigned bit_count = DigitBase == digit_base_2 ? Digits : (Digits * 1000uL) / 301uL + (((Digits * 1000uL) % 301) ? 2u : 1u);
101
+ using rep_type = cpp_int_backend<std::is_void<Allocator>::value ? bit_count : 0, bit_count, std::is_void<Allocator>::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator>;
102
+ using double_rep_type = cpp_int_backend<std::is_void<Allocator>::value ? 2 * bit_count : 0, 2 * bit_count, std::is_void<Allocator>::value ? unsigned_magnitude : signed_magnitude, unchecked, Allocator>;
103
+
104
+ using signed_types = typename rep_type::signed_types;
105
+ using unsigned_types = typename rep_type::unsigned_types;
106
+ using float_types = std::tuple<float, double, long double>;
107
+ using exponent_type = Exponent;
108
+
109
+ static constexpr exponent_type max_exponent_limit = (std::numeric_limits<exponent_type>::max)()- 2 * static_cast<exponent_type>(bit_count);
110
+ static constexpr exponent_type min_exponent_limit = (std::numeric_limits<exponent_type>::min)() + 2 * static_cast<exponent_type>(bit_count);
111
+
112
+ static_assert(MinExponent >= min_exponent_limit, "Template parameter MinExponent is too negative for our internal logic to function correctly, sorry!");
113
+ static_assert(MaxExponent <= max_exponent_limit, "Template parameter MaxExponent is too large for our internal logic to function correctly, sorry!");
114
+ static_assert(MinExponent <= 0, "Template parameter MinExponent can not be positive!");
115
+ static_assert(MaxExponent >= 0, "Template parameter MaxExponent can not be negative!");
116
+
117
+ static constexpr exponent_type max_exponent = MaxExponent == 0 ? max_exponent_limit : MaxExponent;
118
+ static constexpr exponent_type min_exponent = MinExponent == 0 ? min_exponent_limit : MinExponent;
119
+
120
+ static constexpr exponent_type exponent_zero = max_exponent + 1;
121
+ static constexpr exponent_type exponent_infinity = max_exponent + 2;
122
+ static constexpr exponent_type exponent_nan = max_exponent + 3;
123
+
124
+ private:
125
+ rep_type m_data;
126
+ exponent_type m_exponent;
127
+ bool m_sign;
128
+
129
+ public:
130
+ cpp_bin_float() noexcept(noexcept(rep_type())) : m_data(), m_exponent(exponent_zero), m_sign(false) {}
131
+
132
+ cpp_bin_float(const cpp_bin_float& o) noexcept(noexcept(rep_type(std::declval<const rep_type&>())))
133
+ : m_data(o.m_data), m_exponent(o.m_exponent), m_sign(o.m_sign) {}
134
+
135
+ template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
136
+ cpp_bin_float(const cpp_bin_float<D, B, A, E, MinE, MaxE>& o, typename std::enable_if<(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = nullptr)
137
+ {
138
+ *this = o;
139
+ }
140
+ template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
141
+ explicit cpp_bin_float(const cpp_bin_float<D, B, A, E, MinE, MaxE>& o, typename std::enable_if< !(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = nullptr)
142
+ : m_exponent(o.exponent()), m_sign(o.sign())
143
+ {
144
+ *this = o;
145
+ }
146
+ // rvalue copy:
147
+ template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
148
+ cpp_bin_float(cpp_bin_float<D, B, A, E, MinE, MaxE>&& o, typename std::enable_if<(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = nullptr)noexcept(noexcept(rep_type(std::declval<rep_type&&>())))
149
+ {
150
+ *this = std::move(o);
151
+ }
152
+ template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
153
+ explicit cpp_bin_float(cpp_bin_float<D, B, A, E, MinE, MaxE>&& o, typename std::enable_if< !(bit_count >= cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count)>::type const* = nullptr) noexcept(noexcept(rep_type(std::declval<rep_type&&>())))
154
+ : m_exponent(o.exponent()), m_sign(o.sign())
155
+ {
156
+ *this = std::move(o);
157
+ }
158
+ template <class Float>
159
+ cpp_bin_float(const Float& f,
160
+ typename std::enable_if<detail::is_cpp_bin_float_implicitly_constructible_from_type<Float, static_cast<std::ptrdiff_t>(bit_count)>::value>::type const* = nullptr)
161
+ : m_data(), m_exponent(0), m_sign(false)
162
+ {
163
+ this->assign_float(f);
164
+ }
165
+
166
+ template <class Float>
167
+ explicit cpp_bin_float(const Float& f,
168
+ typename std::enable_if<detail::is_cpp_bin_float_explicitly_constructible_from_type<Float, static_cast<std::ptrdiff_t>(bit_count)>::value>::type const* = nullptr)
169
+ : m_data(), m_exponent(0), m_sign(false)
170
+ {
171
+ this->assign_float(f);
172
+ }
173
+ #ifdef BOOST_MP_HAS_FLOAT128_SUPPORT
174
+ template <class Float>
175
+ cpp_bin_float(const Float& f,
176
+ typename std::enable_if<
177
+ std::is_same<Float, float128_type>::value && (static_cast<int>(bit_count) >= 113)>::type const* = nullptr)
178
+ : m_data(), m_exponent(0), m_sign(false)
179
+ {
180
+ this->assign_float(f);
181
+ }
182
+ template <class Float>
183
+ explicit cpp_bin_float(const Float& f,
184
+ typename std::enable_if<
185
+ std::is_same<Float, float128_type>::value && (static_cast<int>(bit_count) < 113)>::type const* = nullptr)
186
+ : m_data(), m_exponent(0), m_sign(false)
187
+ {
188
+ this->assign_float(f);
189
+ }
190
+ #endif
191
+ cpp_bin_float& operator=(const cpp_bin_float& o) noexcept(noexcept(std::declval<rep_type&>() = std::declval<const rep_type&>()))
192
+ {
193
+ m_data = o.m_data;
194
+ m_exponent = o.m_exponent;
195
+ m_sign = o.m_sign;
196
+ return *this;
197
+ }
198
+
199
+ template <class A, class E, E MinE, E MaxE>
200
+ cpp_bin_float& operator=(const cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>& o) noexcept(noexcept(std::declval<rep_type&>() = std::declval<const rep_type&>()))
201
+ {
202
+ m_data = o.bits();
203
+ m_sign = o.sign();
204
+ if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_zero)
205
+ m_exponent = exponent_zero;
206
+ else if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_nan)
207
+ m_exponent = exponent_nan;
208
+ else if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_infinity)
209
+ m_exponent = exponent_infinity;
210
+ else if (o.exponent() > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
211
+ {
212
+ // Overflow:
213
+ exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
214
+ bits() = static_cast<limb_type>(0u);
215
+ }
216
+ else if (o.exponent() < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent)
217
+ {
218
+ // Underflow:
219
+ exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
220
+ bits() = static_cast<limb_type>(0u);
221
+ }
222
+ else
223
+ m_exponent = o.exponent();
224
+ return *this;
225
+ }
226
+ // rvalue copy:
227
+ template <class A, class E, E MinE, E MaxE>
228
+ cpp_bin_float& operator=(cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>&& o) noexcept(noexcept(std::declval<rep_type&>() = std::declval<rep_type&&>()))
229
+ {
230
+ m_data = std::move(o.bits());
231
+ m_sign = o.sign();
232
+ if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_zero)
233
+ m_exponent = exponent_zero;
234
+ else if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_nan)
235
+ m_exponent = exponent_nan;
236
+ else if (o.exponent() == cpp_bin_float<Digits, DigitBase, A, E, MinE, MaxE>::exponent_infinity)
237
+ m_exponent = exponent_infinity;
238
+ else if (o.exponent() > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
239
+ {
240
+ // Overflow:
241
+ exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
242
+ bits() = static_cast<limb_type>(0u);
243
+ }
244
+ else if (o.exponent() < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent)
245
+ {
246
+ // Underflow:
247
+ exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
248
+ bits() = static_cast<limb_type>(0u);
249
+ }
250
+ else
251
+ m_exponent = o.exponent();
252
+ return *this;
253
+ }
254
+ template <unsigned D, digit_base_type B, class A, class E, E MinE, E MaxE>
255
+ cpp_bin_float& operator=(const cpp_bin_float<D, B, A, E, MinE, MaxE>& f)
256
+ {
257
+ switch (eval_fpclassify(f))
258
+ {
259
+ case FP_ZERO:
260
+ m_data = limb_type(0);
261
+ m_sign = f.sign();
262
+ m_exponent = exponent_zero;
263
+ break;
264
+ case FP_NAN:
265
+ m_data = limb_type(0);
266
+ m_sign = false;
267
+ m_exponent = exponent_nan;
268
+ break;
269
+ ;
270
+ case FP_INFINITE:
271
+ m_data = limb_type(0);
272
+ m_sign = f.sign();
273
+ m_exponent = exponent_infinity;
274
+ break;
275
+ default:
276
+ typename cpp_bin_float<D, B, A, E, MinE, MaxE>::rep_type b(f.bits());
277
+ this->exponent() = f.exponent() + (E)bit_count - (E)cpp_bin_float<D, B, A, E, MinE, MaxE>::bit_count;
278
+ this->sign() = f.sign();
279
+ copy_and_round(*this, b);
280
+ }
281
+ return *this;
282
+ }
283
+ #ifdef BOOST_MP_HAS_FLOAT128_SUPPORT
284
+ template <class Float>
285
+ typename std::enable_if<
286
+ (number_category<Float>::value == number_kind_floating_point)
287
+ //&& (std::numeric_limits<Float>::digits <= static_cast<int>(bit_count))
288
+ && ((std::numeric_limits<Float>::radix == 2) || (std::is_same<Float, float128_type>::value)),
289
+ cpp_bin_float&>::type
290
+ operator=(const Float& f)
291
+ #else
292
+ template <class Float>
293
+ typename std::enable_if<
294
+ (number_category<Float>::value == number_kind_floating_point)
295
+ //&& (std::numeric_limits<Float>::digits <= static_cast<int>(bit_count))
296
+ && (std::numeric_limits<Float>::radix == 2),
297
+ cpp_bin_float&>::type
298
+ operator=(const Float& f)
299
+ #endif
300
+ {
301
+ return assign_float(f);
302
+ }
303
+
304
+ #ifdef BOOST_MP_HAS_FLOAT128_SUPPORT
305
+ template <class Float>
306
+ typename std::enable_if<std::is_same<Float, float128_type>::value && (std::numeric_limits<Float>::digits > Digits), cpp_bin_float&>::type assign_float(Float f)
307
+ {
308
+ cpp_bin_float<113, DigitBase, Allocator, Exponent, MinExponent, MaxExponent> bf(f);
309
+ return *this = bf;
310
+ }
311
+ template <class Float>
312
+ typename std::enable_if<std::is_same<Float, float128_type>::value && (std::numeric_limits<Float>::digits <= Digits), cpp_bin_float&>::type assign_float(Float f)
313
+ {
314
+ using default_ops::eval_add;
315
+ using bf_int_type = typename boost::multiprecision::detail::canonical<int, cpp_bin_float>::type;
316
+ if (f == 0)
317
+ {
318
+ m_data = limb_type(0);
319
+ m_sign = (signbitq(f) > 0);
320
+ m_exponent = exponent_zero;
321
+ return *this;
322
+ }
323
+ else if (isnanq(f))
324
+ {
325
+ m_data = limb_type(0);
326
+ m_sign = false;
327
+ m_exponent = exponent_nan;
328
+ return *this;
329
+ }
330
+ else if (isinfq(f))
331
+ {
332
+ m_data = limb_type(0);
333
+ m_sign = (f < 0);
334
+ m_exponent = exponent_infinity;
335
+ return *this;
336
+ }
337
+ if (f < 0)
338
+ {
339
+ *this = -f;
340
+ this->negate();
341
+ return *this;
342
+ }
343
+
344
+ using ui_type = typename std::tuple_element<0, unsigned_types>::type;
345
+ m_data = static_cast<ui_type>(0u);
346
+ m_sign = false;
347
+ m_exponent = 0;
348
+
349
+ constexpr std::ptrdiff_t bits = sizeof(int) * CHAR_BIT - 1 < MaxExponent - 1 ? sizeof(int) * CHAR_BIT - 1 : 3;
350
+ int e;
351
+ f = frexpq(f, &e);
352
+ while (f)
353
+ {
354
+ f = ldexpq(f, bits);
355
+ e -= bits;
356
+ int ipart = static_cast<int>(truncq(f));
357
+ f -= ipart;
358
+ m_exponent += bits;
359
+ cpp_bin_float t;
360
+ t = static_cast<bf_int_type>(ipart);
361
+ eval_add(*this, t);
362
+ }
363
+ m_exponent += static_cast<Exponent>(e);
364
+ if (m_exponent > max_exponent)
365
+ {
366
+ m_exponent = exponent_infinity;
367
+ m_data = static_cast<ui_type>(0u);
368
+ }
369
+ else if (m_exponent < min_exponent)
370
+ {
371
+ m_exponent = exponent_zero;
372
+ m_data = static_cast<ui_type>(0u);
373
+ }
374
+ return *this;
375
+ }
376
+ #endif
377
+ #ifdef BOOST_MP_HAS_FLOAT128_SUPPORT
378
+ template <class Float>
379
+ typename std::enable_if<std::is_floating_point<Float>::value && !std::is_same<Float, float128_type>::value && (std::numeric_limits<Float>::digits > Digits), cpp_bin_float&>::type assign_float(Float f)
380
+ #else
381
+ template <class Float>
382
+ typename std::enable_if<std::is_floating_point<Float>::value && (std::numeric_limits<Float>::digits > Digits), cpp_bin_float&>::type assign_float(Float f)
383
+ #endif
384
+ {
385
+ cpp_bin_float<std::numeric_limits<Float>::digits, DigitBase, Allocator, Exponent, MinExponent, MaxExponent> bf(f);
386
+ return *this = bf;
387
+ }
388
+ #ifdef BOOST_MP_HAS_FLOAT128_SUPPORT
389
+ template <class Float>
390
+ typename std::enable_if<std::is_floating_point<Float>::value && !std::is_same<Float, float128_type>::value && (std::numeric_limits<Float>::digits <= Digits), cpp_bin_float&>::type assign_float(Float f)
391
+ #else
392
+ template <class Float>
393
+ typename std::enable_if<std::is_floating_point<Float>::value && (std::numeric_limits<Float>::digits <= Digits), cpp_bin_float&>::type assign_float(Float f)
394
+ #endif
395
+ {
396
+ using std::frexp;
397
+ using std::ldexp;
398
+ using std::signbit;
399
+ using default_ops::eval_add;
400
+ using bf_int_type = typename boost::multiprecision::detail::canonical<int, cpp_bin_float>::type;
401
+
402
+ switch (BOOST_MP_FPCLASSIFY(f))
403
+ {
404
+ case FP_ZERO:
405
+ m_data = limb_type(0);
406
+ m_sign = ((signbit)(f));
407
+ m_exponent = exponent_zero;
408
+ return *this;
409
+ case FP_NAN:
410
+ m_data = limb_type(0);
411
+ m_sign = false;
412
+ m_exponent = exponent_nan;
413
+ return *this;
414
+ case FP_INFINITE:
415
+ m_data = limb_type(0);
416
+ m_sign = (f < 0);
417
+ m_exponent = exponent_infinity;
418
+ return *this;
419
+ }
420
+ if (f < 0)
421
+ {
422
+ *this = -f;
423
+ this->negate();
424
+ return *this;
425
+ }
426
+
427
+ using ui_type = typename std::tuple_element<0, unsigned_types>::type;
428
+ m_data = static_cast<ui_type>(0u);
429
+ m_sign = false;
430
+ m_exponent = 0;
431
+
432
+ //
433
+ // This code picks off the bits in f a few at a time and injects them into *this.
434
+ // It does not do roundingm so we must have more digits precision in *this than
435
+ // in the floating point value (the normal situation, unless we're emulating another
436
+ // type like float16_t).
437
+ //
438
+ constexpr std::ptrdiff_t bits = static_cast<std::ptrdiff_t>(sizeof(int) * CHAR_BIT - 1) < static_cast<std::ptrdiff_t>(MaxExponent - 1) ? static_cast<std::ptrdiff_t>(sizeof(int) * CHAR_BIT - 1) : 3;
439
+ int e;
440
+ f = frexp(f, &e);
441
+ while (f != static_cast<Float>(0.0F))
442
+ {
443
+ f = ldexp(f, bits);
444
+ e -= static_cast<int>(bits);
445
+ int ipart = boost::multiprecision::detail::itrunc(f);
446
+ f -= static_cast<Float>(ipart);
447
+ m_exponent += static_cast<exponent_type>(bits);
448
+ cpp_bin_float t;
449
+ t = static_cast<bf_int_type>(ipart);
450
+ eval_add(*this, t);
451
+ }
452
+ m_exponent += static_cast<Exponent>(e);
453
+ if (m_exponent > max_exponent)
454
+ {
455
+ m_exponent = exponent_infinity;
456
+ m_data = static_cast<ui_type>(0u);
457
+ }
458
+ else if(m_exponent < min_exponent)
459
+ {
460
+ m_exponent = exponent_zero;
461
+ m_data = static_cast<ui_type>(0u);
462
+ }
463
+ return *this;
464
+ }
465
+
466
+ template <class Float>
467
+ typename std::enable_if<
468
+ (number_category<Float>::value == number_kind_floating_point) && !std::is_floating_point<Float>::value && (number_category<Float>::value == number_kind_floating_point),
469
+ cpp_bin_float&>::type
470
+ assign_float(Float f)
471
+ {
472
+ using default_ops::eval_add;
473
+ using default_ops::eval_convert_to;
474
+ using default_ops::eval_get_sign;
475
+ using default_ops::eval_subtract;
476
+
477
+ using f_int_type = typename boost::multiprecision::detail::canonical<int, Float>::type ;
478
+ using bf_int_type = typename boost::multiprecision::detail::canonical<int, cpp_bin_float>::type;
479
+
480
+ switch (eval_fpclassify(f))
481
+ {
482
+ case FP_ZERO:
483
+ m_data = limb_type(0);
484
+ m_sign = (eval_get_sign(f) > 0);
485
+ m_exponent = exponent_zero;
486
+ return *this;
487
+ case FP_NAN:
488
+ m_data = limb_type(0);
489
+ m_sign = false;
490
+ m_exponent = exponent_nan;
491
+ return *this;
492
+ case FP_INFINITE:
493
+ m_data = limb_type(0);
494
+ m_sign = eval_get_sign(f) < 0;
495
+ m_exponent = exponent_infinity;
496
+ return *this;
497
+ }
498
+ if (eval_get_sign(f) < 0)
499
+ {
500
+ f.negate();
501
+ assign_float(f);
502
+ this->negate();
503
+ return *this;
504
+ }
505
+
506
+ using ui_type = typename std::tuple_element<0, unsigned_types>::type;
507
+ m_data = static_cast<ui_type>(0u);
508
+ m_sign = false;
509
+ m_exponent = 0;
510
+
511
+ constexpr std::ptrdiff_t bits = sizeof(int) * CHAR_BIT - 1;
512
+ int e;
513
+ eval_frexp(f, f, &e);
514
+ while (eval_get_sign(f) != 0)
515
+ {
516
+ eval_ldexp(f, f, bits);
517
+ e -= bits;
518
+ int ipart;
519
+ eval_convert_to(&ipart, f);
520
+ eval_subtract(f, static_cast<f_int_type>(ipart));
521
+ m_exponent += bits;
522
+ eval_add(*this, static_cast<bf_int_type>(ipart));
523
+ }
524
+ m_exponent += e;
525
+ if (m_exponent > max_exponent)
526
+ m_exponent = exponent_infinity;
527
+ if (m_exponent < min_exponent)
528
+ {
529
+ m_data = limb_type(0u);
530
+ m_exponent = exponent_zero;
531
+ m_sign = (eval_get_sign(f) > 0);
532
+ }
533
+ else if (eval_get_sign(m_data) == 0)
534
+ {
535
+ m_exponent = exponent_zero;
536
+ m_sign = (eval_get_sign(f) > 0);
537
+ }
538
+ return *this;
539
+ }
540
+ template <class B, expression_template_option et>
541
+ cpp_bin_float& assign_float(const number<B, et>& f)
542
+ {
543
+ return assign_float(f.backend());
544
+ }
545
+
546
+ template <class I>
547
+ typename std::enable_if<boost::multiprecision::detail::is_integral<I>::value, cpp_bin_float&>::type operator=(const I& i)
548
+ {
549
+ using default_ops::eval_bit_test;
550
+ if (!i)
551
+ {
552
+ m_data = static_cast<limb_type>(0);
553
+ m_exponent = exponent_zero;
554
+ m_sign = false;
555
+ }
556
+ else
557
+ {
558
+ using ui_type = typename boost::multiprecision::detail::make_unsigned<I>::type ;
559
+ ui_type fi = static_cast<ui_type>(boost::multiprecision::detail::unsigned_abs(i));
560
+ using ar_type = typename boost::multiprecision::detail::canonical<ui_type, rep_type>::type;
561
+ m_data = static_cast<ar_type>(fi);
562
+ std::size_t shift = msb(fi);
563
+ if (shift > max_exponent)
564
+ {
565
+ m_exponent = exponent_infinity;
566
+ m_data = static_cast<limb_type>(0);
567
+ }
568
+ else if (shift >= bit_count)
569
+ {
570
+ m_exponent = static_cast<Exponent>(shift);
571
+ m_data = static_cast<ar_type>(fi >> (shift + 1 - bit_count));
572
+ }
573
+ else
574
+ {
575
+ m_exponent = static_cast<Exponent>(shift);
576
+ eval_left_shift(m_data, bit_count - shift - 1);
577
+ }
578
+ BOOST_MP_ASSERT((m_exponent == exponent_infinity) || eval_bit_test(m_data, bit_count - 1));
579
+ m_sign = detail::is_negative(i);
580
+ }
581
+ return *this;
582
+ }
583
+
584
+ cpp_bin_float& operator=(const char* s);
585
+
586
+ void swap(cpp_bin_float& o) noexcept
587
+ {
588
+ m_data.swap(o.m_data);
589
+ std::swap(m_exponent, o.m_exponent);
590
+ std::swap(m_sign, o.m_sign);
591
+ }
592
+
593
+ std::string str(std::streamsize dig, std::ios_base::fmtflags f) const;
594
+
595
+ void negate()
596
+ {
597
+ if (m_exponent != exponent_nan)
598
+ m_sign = !m_sign;
599
+ }
600
+
601
+ int compare(const cpp_bin_float& o) const noexcept
602
+ {
603
+ if (m_sign != o.m_sign)
604
+ return (m_exponent == exponent_zero) && (m_exponent == o.m_exponent) ? 0 : m_sign ? -1 : 1;
605
+ int result;
606
+ if (m_exponent == exponent_nan)
607
+ return -1;
608
+ else if (m_exponent != o.m_exponent)
609
+ {
610
+ if (m_exponent == exponent_zero)
611
+ result = -1;
612
+ else if (o.m_exponent == exponent_zero)
613
+ result = 1;
614
+ else
615
+ result = m_exponent > o.m_exponent ? 1 : -1;
616
+ }
617
+ else
618
+ result = m_data.compare(o.m_data);
619
+ if (m_sign)
620
+ result = -result;
621
+ return result;
622
+ }
623
+ template <class A>
624
+ int compare(const A& o) const noexcept
625
+ {
626
+ cpp_bin_float b;
627
+ b = o;
628
+ return compare(b);
629
+ }
630
+
631
+ rep_type& bits() { return m_data; }
632
+ const rep_type& bits() const { return m_data; }
633
+ exponent_type& exponent() { return m_exponent; }
634
+ const exponent_type& exponent() const { return m_exponent; }
635
+ bool& sign() { return m_sign; }
636
+ const bool& sign() const { return m_sign; }
637
+ void check_invariants()
638
+ {
639
+ using default_ops::eval_bit_test;
640
+ using default_ops::eval_is_zero;
641
+ if ((m_exponent <= max_exponent) && (m_exponent >= min_exponent))
642
+ {
643
+ BOOST_MP_ASSERT(eval_bit_test(m_data, bit_count - 1));
644
+ }
645
+ else
646
+ {
647
+ BOOST_MP_ASSERT(m_exponent > max_exponent);
648
+ BOOST_MP_ASSERT(m_exponent <= exponent_nan);
649
+ BOOST_MP_ASSERT(eval_is_zero(m_data));
650
+ }
651
+ }
652
+
653
+ #ifndef BOOST_MP_STANDALONE
654
+ template <class Archive>
655
+ void serialize(Archive& ar, const unsigned int /*version*/)
656
+ {
657
+ ar& boost::make_nvp("data", m_data);
658
+ ar& boost::make_nvp("exponent", m_exponent);
659
+ ar& boost::make_nvp("sign", m_sign);
660
+ }
661
+ #endif
662
+ };
663
+
664
+ #ifdef BOOST_MSVC
665
+ #pragma warning(pop)
666
+ #endif
667
+
668
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class Int>
669
+ inline void copy_and_round(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, Int& arg, std::ptrdiff_t bits_to_keep = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
670
+ {
671
+ // Precondition: exponent of res must have been set before this function is called
672
+ // as we may need to adjust it based on how many bits_to_keep in arg are set.
673
+ using default_ops::eval_bit_test;
674
+ using default_ops::eval_get_sign;
675
+ using default_ops::eval_increment;
676
+ using default_ops::eval_left_shift;
677
+ using default_ops::eval_lsb;
678
+ using default_ops::eval_msb;
679
+ using default_ops::eval_right_shift;
680
+
681
+ // cancellation may have resulted in arg being all zeros:
682
+ if (eval_get_sign(arg) == 0)
683
+ {
684
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
685
+ res.sign() = false;
686
+ res.bits() = static_cast<limb_type>(0u);
687
+ return;
688
+ }
689
+ std::ptrdiff_t msb = static_cast<std::ptrdiff_t>(eval_msb(arg));
690
+ if (static_cast<std::ptrdiff_t >(bits_to_keep) > msb + 1)
691
+ {
692
+ // Must have had cancellation in subtraction,
693
+ // or be converting from a narrower type, so shift left:
694
+ res.bits() = arg;
695
+ eval_left_shift(res.bits(), static_cast<double_limb_type>(bits_to_keep - msb - 1));
696
+ res.exponent() -= static_cast<Exponent>(bits_to_keep - msb - 1);
697
+ }
698
+ else if (static_cast<std::ptrdiff_t >(bits_to_keep) < msb + 1)
699
+ {
700
+ // We have more bits_to_keep than we need, so round as required,
701
+ // first get the rounding bit:
702
+ bool roundup = eval_bit_test(arg, static_cast<std::size_t>(msb - bits_to_keep));
703
+ // Then check for a tie:
704
+ if (roundup && (msb - bits_to_keep == static_cast<std::ptrdiff_t>(eval_lsb(arg))))
705
+ {
706
+ // Ties round towards even:
707
+ if (!eval_bit_test(arg, static_cast<std::size_t>(msb - bits_to_keep + 1)))
708
+ roundup = false;
709
+ }
710
+ // Shift off the bits_to_keep we don't need:
711
+ eval_right_shift(arg, static_cast<double_limb_type>(msb - bits_to_keep + 1));
712
+ res.exponent() += static_cast<Exponent>(msb - bits_to_keep + 1);
713
+ if (roundup)
714
+ {
715
+ eval_increment(arg);
716
+ if (bits_to_keep)
717
+ {
718
+ if (eval_bit_test(arg, static_cast<std::size_t>(bits_to_keep)))
719
+ {
720
+ // This happens very very rairly, all the bits left after
721
+ // truncation must be 1's and we're rounding up an order of magnitude:
722
+ eval_right_shift(arg, 1u);
723
+ ++res.exponent();
724
+ }
725
+ }
726
+ else
727
+ {
728
+ // We get here when bits_to_keep is zero but we're rounding up,
729
+ // as a result we end up with a single digit that is a 1:
730
+ ++bits_to_keep;
731
+ }
732
+ }
733
+ if (bits_to_keep != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
734
+ {
735
+ // Normalize result when we're rounding to fewer bits than we can hold, only happens in conversions
736
+ // to narrower types:
737
+ eval_left_shift(arg, static_cast<double_limb_type>(static_cast<std::ptrdiff_t>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - bits_to_keep));
738
+ res.exponent() -= static_cast<Exponent>(static_cast<std::ptrdiff_t>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - bits_to_keep);
739
+ }
740
+ res.bits() = arg;
741
+ }
742
+ else
743
+ {
744
+ res.bits() = arg;
745
+ }
746
+ if (!bits_to_keep && !res.bits().limbs()[0])
747
+ {
748
+ // We're keeping zero bits and did not round up, so result is zero:
749
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
750
+ return;
751
+ }
752
+ // Result must be normalized:
753
+ BOOST_MP_ASSERT(((std::ptrdiff_t )eval_msb(res.bits()) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
754
+
755
+ if (res.exponent() > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent)
756
+ {
757
+ // Overflow:
758
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
759
+ res.bits() = static_cast<limb_type>(0u);
760
+ }
761
+ else if (res.exponent() < cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent)
762
+ {
763
+ // Underflow:
764
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
765
+ res.bits() = static_cast<limb_type>(0u);
766
+ }
767
+ }
768
+
769
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class BinFloat2, class BinFloat3>
770
+ inline void do_eval_add(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
771
+ const BinFloat2& a, const BinFloat3& b)
772
+ {
773
+ if (a.exponent() < b.exponent())
774
+ {
775
+ bool s = a.sign();
776
+ do_eval_add(res, b, a);
777
+ if (res.sign() != s)
778
+ res.negate();
779
+ return;
780
+ }
781
+
782
+ using default_ops::eval_add;
783
+ using default_ops::eval_bit_test;
784
+
785
+ using exponent_type = typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type;
786
+
787
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
788
+
789
+ // Special cases first:
790
+ switch (a.exponent())
791
+ {
792
+ case BinFloat2::exponent_zero:
793
+ {
794
+ bool s = a.sign();
795
+ res = b;
796
+ res.sign() = s;
797
+ return;
798
+ }
799
+ case BinFloat2::exponent_infinity:
800
+ if (b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan)
801
+ res = b;
802
+ else
803
+ res = a;
804
+ return; // result is still infinite.
805
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
806
+ res = a;
807
+ return; // result is still a NaN.
808
+ }
809
+ switch (b.exponent())
810
+ {
811
+ case BinFloat3::exponent_zero:
812
+ res = a;
813
+ return;
814
+ case BinFloat3::exponent_infinity:
815
+ res = b;
816
+ if (res.sign())
817
+ res.negate();
818
+ return; // result is infinite.
819
+ case BinFloat3::exponent_nan:
820
+ res = b;
821
+ return; // result is a NaN.
822
+ }
823
+
824
+ static_assert((std::numeric_limits<exponent_type>::max)() - cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count > cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent, "Exponent range check failed");
825
+
826
+ bool s = a.sign();
827
+ dt = a.bits();
828
+ if (a.exponent() > (std::ptrdiff_t )cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + b.exponent())
829
+ {
830
+ res.exponent() = a.exponent();
831
+ }
832
+ else
833
+ {
834
+ exponent_type e_diff = a.exponent() - b.exponent();
835
+ BOOST_MP_ASSERT(e_diff >= 0);
836
+ eval_left_shift(dt, static_cast<double_limb_type>(e_diff));
837
+ res.exponent() = a.exponent() - e_diff;
838
+ eval_add(dt, b.bits());
839
+ }
840
+
841
+ copy_and_round(res, dt);
842
+ res.check_invariants();
843
+ if (res.sign() != s)
844
+ res.negate();
845
+ }
846
+
847
+ template <class BinFloat1, class BinFloat2, class BinFloat3>
848
+ inline void do_eval_subtract(BinFloat1& res, const BinFloat2& a, const BinFloat3& b)
849
+ {
850
+ using default_ops::eval_bit_test;
851
+ using default_ops::eval_decrement;
852
+ using default_ops::eval_subtract;
853
+
854
+ typename BinFloat1::double_rep_type dt;
855
+
856
+ // Special cases first:
857
+ switch (a.exponent())
858
+ {
859
+ case BinFloat2::exponent_zero:
860
+ if (b.exponent() == BinFloat3::exponent_nan)
861
+ res = std::numeric_limits<number<BinFloat1> >::quiet_NaN().backend();
862
+ else
863
+ {
864
+ bool s = a.sign();
865
+ res = b;
866
+ if (res.exponent() == BinFloat1::exponent_zero)
867
+ res.sign() = false;
868
+ else if (res.sign() == s)
869
+ res.negate();
870
+ }
871
+ return;
872
+ case BinFloat2::exponent_infinity:
873
+ if ((b.exponent() == BinFloat3::exponent_nan) || (b.exponent() == BinFloat3::exponent_infinity))
874
+ res = std::numeric_limits<number<BinFloat1> >::quiet_NaN().backend();
875
+ else
876
+ res = a;
877
+ return;
878
+ case BinFloat2::exponent_nan:
879
+ res = a;
880
+ return; // result is still a NaN.
881
+ }
882
+ switch (b.exponent())
883
+ {
884
+ case BinFloat3::exponent_zero:
885
+ res = a;
886
+ return;
887
+ case BinFloat3::exponent_infinity:
888
+ res.exponent() = BinFloat1::exponent_infinity;
889
+ res.sign() = !a.sign();
890
+ res.bits() = static_cast<limb_type>(0u);
891
+ return; // result is a NaN.
892
+ case BinFloat3::exponent_nan:
893
+ res = b;
894
+ return; // result is still a NaN.
895
+ }
896
+
897
+ bool s = a.sign();
898
+ if ((a.exponent() > b.exponent()) || ((a.exponent() == b.exponent()) && a.bits().compare(b.bits()) >= 0))
899
+ {
900
+ dt = a.bits();
901
+ if (a.exponent() <= (std::ptrdiff_t )BinFloat1::bit_count + b.exponent())
902
+ {
903
+ typename BinFloat1::exponent_type e_diff = a.exponent() - b.exponent();
904
+ eval_left_shift(dt, static_cast<double_limb_type>(e_diff));
905
+ res.exponent() = a.exponent() - e_diff;
906
+ eval_subtract(dt, b.bits());
907
+ }
908
+ else if (a.exponent() == (std::ptrdiff_t )BinFloat1::bit_count + b.exponent() + 1)
909
+ {
910
+ if ((eval_lsb(a.bits()) == BinFloat1::bit_count - 1)
911
+ && (eval_lsb(b.bits()) != BinFloat1::bit_count - 1))
912
+ {
913
+ eval_left_shift(dt, 1);
914
+ eval_decrement(dt);
915
+ res.exponent() = a.exponent() - 1;
916
+ }
917
+ else
918
+ res.exponent() = a.exponent();
919
+ }
920
+ else
921
+ res.exponent() = a.exponent();
922
+ }
923
+ else
924
+ {
925
+ dt = b.bits();
926
+ if (b.exponent() <= (std::ptrdiff_t )BinFloat1::bit_count + a.exponent())
927
+ {
928
+ typename BinFloat1::exponent_type e_diff = a.exponent() - b.exponent();
929
+ eval_left_shift(dt, static_cast<double_limb_type>(-e_diff));
930
+ res.exponent() = b.exponent() + e_diff;
931
+ eval_subtract(dt, a.bits());
932
+ }
933
+ else if (b.exponent() == (std::ptrdiff_t )BinFloat1::bit_count + a.exponent() + 1)
934
+ {
935
+ if ((eval_lsb(a.bits()) != BinFloat1::bit_count - 1)
936
+ && eval_lsb(b.bits()))
937
+ {
938
+ eval_left_shift(dt, 1);
939
+ eval_decrement(dt);
940
+ res.exponent() = b.exponent() - 1;
941
+ }
942
+ else
943
+ res.exponent() = b.exponent();
944
+ }
945
+ else
946
+ res.exponent() = b.exponent();
947
+ s = !s;
948
+ }
949
+
950
+ copy_and_round(res, dt);
951
+ if (res.exponent() == BinFloat1::exponent_zero)
952
+ res.sign() = false;
953
+ else if (res.sign() != s)
954
+ res.negate();
955
+ res.check_invariants();
956
+ }
957
+
958
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
959
+ class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2,
960
+ class Allocator3, class Exponent3, Exponent MinE3, Exponent MaxE3>
961
+ inline void eval_add(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
962
+ const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a,
963
+ const cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>& b)
964
+ {
965
+ if (a.sign() == b.sign())
966
+ do_eval_add(res, a, b);
967
+ else
968
+ do_eval_subtract(res, a, b);
969
+ }
970
+
971
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
972
+ class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
973
+ inline void eval_add(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
974
+ const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a)
975
+ {
976
+ return eval_add(res, res, a);
977
+ }
978
+
979
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
980
+ class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2,
981
+ class Allocator3, class Exponent3, Exponent MinE3, Exponent MaxE3>
982
+ inline void eval_subtract(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
983
+ const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a,
984
+ const cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>& b)
985
+ {
986
+ if (a.sign() != b.sign())
987
+ do_eval_add(res, a, b);
988
+ else
989
+ do_eval_subtract(res, a, b);
990
+ }
991
+
992
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
993
+ class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
994
+ inline void eval_subtract(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
995
+ const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a)
996
+ {
997
+ return eval_subtract(res, res, a);
998
+ }
999
+
1000
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1001
+ class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2,
1002
+ class Allocator3, class Exponent3, Exponent MinE3, Exponent MaxE3>
1003
+ inline void eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
1004
+ const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a,
1005
+ const cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>& b)
1006
+ {
1007
+ using default_ops::eval_bit_test;
1008
+ using default_ops::eval_multiply;
1009
+
1010
+ // Special cases first:
1011
+ switch (a.exponent())
1012
+ {
1013
+ case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_zero:
1014
+ {
1015
+ if (b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_nan)
1016
+ res = b;
1017
+ else if (b.exponent() == cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_infinity)
1018
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1019
+ else
1020
+ {
1021
+ bool s = a.sign() != b.sign();
1022
+ res = a;
1023
+ res.sign() = s;
1024
+ }
1025
+ return;
1026
+ }
1027
+ case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_infinity:
1028
+ switch (b.exponent())
1029
+ {
1030
+ case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_zero:
1031
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1032
+ break;
1033
+ case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_nan:
1034
+ res = b;
1035
+ break;
1036
+ default:
1037
+ bool s = a.sign() != b.sign();
1038
+ res = a;
1039
+ res.sign() = s;
1040
+ break;
1041
+ }
1042
+ return;
1043
+ case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_nan:
1044
+ res = a;
1045
+ return;
1046
+ }
1047
+ if (b.exponent() > cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::max_exponent)
1048
+ {
1049
+ bool s = a.sign() != b.sign();
1050
+ res = b;
1051
+ res.sign() = s;
1052
+ return;
1053
+ }
1054
+ if ((a.exponent() > 0) && (b.exponent() > 0))
1055
+ {
1056
+ if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent + 2 - a.exponent() < b.exponent())
1057
+ {
1058
+ // We will certainly overflow:
1059
+ bool s = a.sign() != b.sign();
1060
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
1061
+ res.sign() = s;
1062
+ res.bits() = static_cast<limb_type>(0u);
1063
+ return;
1064
+ }
1065
+ }
1066
+ if ((a.exponent() < 0) && (b.exponent() < 0))
1067
+ {
1068
+ if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent - 2 - a.exponent() > b.exponent())
1069
+ {
1070
+ // We will certainly underflow:
1071
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
1072
+ res.sign() = a.sign() != b.sign();
1073
+ res.bits() = static_cast<limb_type>(0u);
1074
+ return;
1075
+ }
1076
+ }
1077
+
1078
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
1079
+ eval_multiply(dt, a.bits(), b.bits());
1080
+ res.exponent() = a.exponent() + b.exponent() - (Exponent)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count + 1;
1081
+ copy_and_round(res, dt);
1082
+ res.check_invariants();
1083
+ res.sign() = a.sign() != b.sign();
1084
+ }
1085
+
1086
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1087
+ class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
1088
+ inline void eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
1089
+ const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a)
1090
+ {
1091
+ eval_multiply(res, res, a);
1092
+ }
1093
+
1094
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1095
+ class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2, class U>
1096
+ inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<U>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
1097
+ const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a, const U& b)
1098
+ {
1099
+ using default_ops::eval_bit_test;
1100
+ using default_ops::eval_multiply;
1101
+
1102
+ bool s = a.sign(); // saved for later in case a and res are the same object.
1103
+
1104
+ // Special cases first:
1105
+ switch (a.exponent())
1106
+ {
1107
+ case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_zero:
1108
+ {
1109
+ res = a;
1110
+ res.sign() = s;
1111
+ return;
1112
+ }
1113
+ case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_infinity:
1114
+ if (b == 0)
1115
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1116
+ else
1117
+ res = a;
1118
+ return;
1119
+ case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_nan:
1120
+ res = a;
1121
+ return;
1122
+ }
1123
+
1124
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type dt;
1125
+ using canon_ui_type = typename boost::multiprecision::detail::canonical<U, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::type;
1126
+ eval_multiply(dt, a.bits(), static_cast<canon_ui_type>(b));
1127
+ res.exponent() = a.exponent();
1128
+ copy_and_round(res, dt);
1129
+ res.check_invariants();
1130
+ res.sign() = s;
1131
+ }
1132
+
1133
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
1134
+ inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<U>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const U& b)
1135
+ {
1136
+ eval_multiply(res, res, b);
1137
+ }
1138
+
1139
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1140
+ class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2, class S>
1141
+ inline typename std::enable_if<boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
1142
+ const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& a, const S& b)
1143
+ {
1144
+ using ui_type = typename boost::multiprecision::detail::make_unsigned<S>::type;
1145
+ eval_multiply(res, a, static_cast<ui_type>(boost::multiprecision::detail::unsigned_abs(b)));
1146
+ if (b < 0)
1147
+ res.negate();
1148
+ }
1149
+
1150
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S>
1151
+ inline typename std::enable_if<boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value>::type eval_multiply(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const S& b)
1152
+ {
1153
+ eval_multiply(res, res, b);
1154
+ }
1155
+
1156
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1157
+ class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2,
1158
+ class Allocator3, class Exponent3, Exponent MinE3, Exponent MaxE3>
1159
+ inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
1160
+ const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& u,
1161
+ const cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>& v)
1162
+ {
1163
+ #ifdef BOOST_MSVC
1164
+ #pragma warning(push)
1165
+ #pragma warning(disable : 6326) // comparison of two constants
1166
+ #endif
1167
+ using default_ops::eval_bit_test;
1168
+ using default_ops::eval_get_sign;
1169
+ using default_ops::eval_increment;
1170
+ using default_ops::eval_qr;
1171
+ using default_ops::eval_subtract;
1172
+
1173
+ //
1174
+ // Special cases first:
1175
+ //
1176
+ switch (u.exponent())
1177
+ {
1178
+ case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_zero:
1179
+ {
1180
+ switch (v.exponent())
1181
+ {
1182
+ case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_zero:
1183
+ case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_nan:
1184
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1185
+ return;
1186
+ }
1187
+ bool s = u.sign() != v.sign();
1188
+ res = u;
1189
+ res.sign() = s;
1190
+ return;
1191
+ }
1192
+ case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_infinity:
1193
+ {
1194
+ switch (v.exponent())
1195
+ {
1196
+ case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_infinity:
1197
+ case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_nan:
1198
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1199
+ return;
1200
+ }
1201
+ bool s = u.sign() != v.sign();
1202
+ res = u;
1203
+ res.sign() = s;
1204
+ return;
1205
+ }
1206
+ case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_nan:
1207
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1208
+ return;
1209
+ }
1210
+ switch (v.exponent())
1211
+ {
1212
+ case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_zero:
1213
+ {
1214
+ bool s = u.sign() != v.sign();
1215
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
1216
+ res.sign() = s;
1217
+ return;
1218
+ }
1219
+ case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_infinity:
1220
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
1221
+ res.bits() = limb_type(0);
1222
+ res.sign() = u.sign() != v.sign();
1223
+ return;
1224
+ case cpp_bin_float<Digits, DigitBase, Allocator3, Exponent3, MinE3, MaxE3>::exponent_nan:
1225
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1226
+ return;
1227
+ }
1228
+
1229
+ // We can scale u and v so that both are integers, then perform integer
1230
+ // division to obtain quotient q and remainder r, such that:
1231
+ //
1232
+ // q * v + r = u
1233
+ //
1234
+ // and hense:
1235
+ //
1236
+ // q + r/v = u/v
1237
+ //
1238
+ // From this, assuming q has cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count
1239
+ // bits we only need to determine whether
1240
+ // r/v is less than, equal to, or greater than 0.5 to determine rounding -
1241
+ // this we can do with a shift and comparison.
1242
+ //
1243
+ // We can set the exponent and sign of the result up front:
1244
+ //
1245
+ if ((v.exponent() < 0) && (u.exponent() > 0))
1246
+ {
1247
+ // Check for overflow:
1248
+ if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent + v.exponent() < u.exponent() - 1)
1249
+ {
1250
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
1251
+ res.sign() = u.sign() != v.sign();
1252
+ res.bits() = static_cast<limb_type>(0u);
1253
+ return;
1254
+ }
1255
+ }
1256
+ else if ((v.exponent() > 0) && (u.exponent() < 0))
1257
+ {
1258
+ // Check for underflow:
1259
+ if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent + v.exponent() > u.exponent())
1260
+ {
1261
+ // We will certainly underflow:
1262
+ res.exponent() = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
1263
+ res.sign() = u.sign() != v.sign();
1264
+ res.bits() = static_cast<limb_type>(0u);
1265
+ return;
1266
+ }
1267
+ }
1268
+ res.exponent() = u.exponent() - v.exponent() - 1;
1269
+ res.sign() = u.sign() != v.sign();
1270
+ //
1271
+ // Now get the quotient and remainder:
1272
+ //
1273
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(u.bits()), t2(v.bits()), q, r;
1274
+ eval_left_shift(t, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count);
1275
+ eval_qr(t, t2, q, r);
1276
+ //
1277
+ // We now have either "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count"
1278
+ // or "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1" significant
1279
+ // bits in q.
1280
+ //
1281
+ constexpr unsigned limb_bits = sizeof(limb_type) * CHAR_BIT;
1282
+ if (eval_bit_test(q, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
1283
+ {
1284
+ //
1285
+ // OK we have cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1 bits,
1286
+ // so we already have rounding info,
1287
+ // we just need to changes things if the last bit is 1 and either the
1288
+ // remainder is non-zero (ie we do not have a tie) or the quotient would
1289
+ // be odd if it were shifted to the correct number of bits (ie a tiebreak).
1290
+ //
1291
+ BOOST_MP_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count));
1292
+ if ((q.limbs()[0] & 1u) && (eval_get_sign(r) || (q.limbs()[0] & 2u)))
1293
+ {
1294
+ eval_increment(q);
1295
+ }
1296
+ }
1297
+ else
1298
+ {
1299
+ //
1300
+ // We have exactly "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" bits in q.
1301
+ // Get rounding info, which we can get by comparing 2r with v.
1302
+ // We want to call copy_and_round to handle rounding and general cleanup,
1303
+ // so we'll left shift q and add some fake digits on the end to represent
1304
+ // how we'll be rounding.
1305
+ //
1306
+ using local_exponent_type = typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type;
1307
+
1308
+ BOOST_MP_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
1309
+ constexpr unsigned lshift = (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits) ? 2 : limb_bits;
1310
+ eval_left_shift(q, lshift);
1311
+ res.exponent() -= static_cast<local_exponent_type>(lshift);
1312
+ eval_left_shift(r, 1u);
1313
+ int c = r.compare(v.bits());
1314
+ if (c == 0)
1315
+ q.limbs()[0] |= static_cast<limb_type>(1u) << (lshift - 1);
1316
+ else if (c > 0)
1317
+ q.limbs()[0] |= (static_cast<limb_type>(1u) << (lshift - 1)) + static_cast<limb_type>(1u);
1318
+ }
1319
+ copy_and_round(res, q);
1320
+ #ifdef BOOST_MSVC
1321
+ #pragma warning(pop)
1322
+ #endif
1323
+ }
1324
+
1325
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1326
+ class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
1327
+ inline void eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
1328
+ const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& arg)
1329
+ {
1330
+ eval_divide(res, res, arg);
1331
+ }
1332
+
1333
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1334
+ class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2, class U>
1335
+ inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<U>::value && (std::numeric_limits<U>::digits <= Digits)>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
1336
+ const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& u, const U& v)
1337
+ {
1338
+ #ifdef BOOST_MSVC
1339
+ #pragma warning(push)
1340
+ #pragma warning(disable : 6326) // comparison of two constants
1341
+ #endif
1342
+ using default_ops::eval_bit_test;
1343
+ using default_ops::eval_get_sign;
1344
+ using default_ops::eval_increment;
1345
+ using default_ops::eval_qr;
1346
+ using default_ops::eval_subtract;
1347
+
1348
+ //
1349
+ // Special cases first:
1350
+ //
1351
+ switch (u.exponent())
1352
+ {
1353
+ case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_zero:
1354
+ {
1355
+ if (v == 0)
1356
+ {
1357
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1358
+ return;
1359
+ }
1360
+ bool s = u.sign() != (v < 0);
1361
+ res = u;
1362
+ res.sign() = s;
1363
+ return;
1364
+ }
1365
+ case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_infinity:
1366
+ res = u;
1367
+ return;
1368
+ case cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>::exponent_nan:
1369
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1370
+ return;
1371
+ }
1372
+ if (v == 0)
1373
+ {
1374
+ bool s = u.sign();
1375
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
1376
+ res.sign() = s;
1377
+ return;
1378
+ }
1379
+
1380
+ // We can scale u and v so that both are integers, then perform integer
1381
+ // division to obtain quotient q and remainder r, such that:
1382
+ //
1383
+ // q * v + r = u
1384
+ //
1385
+ // and hense:
1386
+ //
1387
+ // q + r/v = u/v
1388
+ //
1389
+ // From this, assuming q has "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count, we only need to determine whether
1390
+ // r/v is less than, equal to, or greater than 0.5 to determine rounding -
1391
+ // this we can do with a shift and comparison.
1392
+ //
1393
+ // We can set the exponent and sign of the result up front:
1394
+ //
1395
+ std::ptrdiff_t gb = static_cast<std::ptrdiff_t>(msb(v));
1396
+ res.exponent() = u.exponent() - static_cast<Exponent>(gb) - static_cast<Exponent>(1);
1397
+ res.sign() = u.sign();
1398
+ //
1399
+ // Now get the quotient and remainder:
1400
+ //
1401
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(u.bits()), q, r;
1402
+ eval_left_shift(t, static_cast<double_limb_type>(gb + 1));
1403
+ eval_qr(t, number<typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::canonical_value(v), q, r);
1404
+ //
1405
+ // We now have either "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" or "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1" significant cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in q.
1406
+ //
1407
+ constexpr unsigned limb_bits = sizeof(limb_type) * CHAR_BIT;
1408
+ if (eval_bit_test(q, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
1409
+ {
1410
+ //
1411
+ // OK we have cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count+1 cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count, so we already have rounding info,
1412
+ // we just need to changes things if the last bit is 1 and the
1413
+ // remainder is non-zero (ie we do not have a tie).
1414
+ //
1415
+ BOOST_MP_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count));
1416
+ if ((q.limbs()[0] & 1u) && eval_get_sign(r))
1417
+ {
1418
+ eval_increment(q);
1419
+ }
1420
+ }
1421
+ else
1422
+ {
1423
+ //
1424
+ // We have exactly "cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count" cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in q.
1425
+ // Get rounding info, which we can get by comparing 2r with v.
1426
+ // We want to call copy_and_round to handle rounding and general cleanup,
1427
+ // so we'll left shift q and add some fake cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count on the end to represent
1428
+ // how we'll be rounding.
1429
+ //
1430
+ using local_exponent_type = typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type;
1431
+
1432
+ BOOST_MP_ASSERT((eval_msb(q) == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1));
1433
+ constexpr unsigned lshift = cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count < limb_bits ? 2 : limb_bits;
1434
+ eval_left_shift(q, lshift);
1435
+ res.exponent() -= static_cast<local_exponent_type>(lshift);
1436
+ eval_left_shift(r, 1u);
1437
+ int c = r.compare(number<typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type>::canonical_value(v));
1438
+ if (c == 0)
1439
+ q.limbs()[0] |= static_cast<limb_type>(1u) << (lshift - 1);
1440
+ else if (c > 0)
1441
+ q.limbs()[0] |= (static_cast<limb_type>(1u) << (lshift - 1)) + static_cast<limb_type>(1u);
1442
+ }
1443
+ copy_and_round(res, q);
1444
+ #ifdef BOOST_MSVC
1445
+ #pragma warning(pop)
1446
+ #endif
1447
+ }
1448
+
1449
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class U>
1450
+ inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<U>::value && (std::numeric_limits<U>::digits <= Digits)>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const U& v)
1451
+ {
1452
+ eval_divide(res, res, v);
1453
+ }
1454
+
1455
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1456
+ class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2, class S>
1457
+ inline typename std::enable_if<boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value && (std::numeric_limits<S>::digits <= Digits)>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res,
1458
+ const cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2>& u, const S& v)
1459
+ {
1460
+ using ui_type = typename boost::multiprecision::detail::make_unsigned<S>::type;
1461
+ eval_divide(res, u, static_cast<ui_type>(boost::multiprecision::detail::unsigned_abs(v)));
1462
+ if (v < 0)
1463
+ res.negate();
1464
+ }
1465
+
1466
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class S>
1467
+ inline typename std::enable_if<boost::multiprecision::detail::is_signed<S>::value && boost::multiprecision::detail::is_integral<S>::value && (std::numeric_limits<S>::digits <= Digits)>::type eval_divide(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const S& v)
1468
+ {
1469
+ eval_divide(res, res, v);
1470
+ }
1471
+
1472
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1473
+ inline int eval_get_sign(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1474
+ {
1475
+ return arg.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero ? 0 : arg.sign() ? -1 : 1;
1476
+ }
1477
+
1478
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1479
+ inline bool eval_is_zero(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1480
+ {
1481
+ return arg.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero;
1482
+ }
1483
+
1484
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1485
+ inline bool eval_eq(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& a, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& b)
1486
+ {
1487
+ if (a.exponent() == b.exponent())
1488
+ {
1489
+ if (a.exponent() == cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero)
1490
+ return true;
1491
+ return (a.sign() == b.sign()) && (a.bits().compare(b.bits()) == 0) && (a.exponent() != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan);
1492
+ }
1493
+ return false;
1494
+ }
1495
+
1496
+ template <class I, unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1497
+ inline void convert_to_signed_int(I* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1498
+ {
1499
+ static constexpr int digits = std::numeric_limits<I>::is_specialized ? std::numeric_limits<I>::digits : sizeof(I) * CHAR_BIT - 1;
1500
+ static constexpr I max_val = std::numeric_limits<I>::is_specialized ? (std::numeric_limits<I>::max)() : (((I(1) << (sizeof(I) * CHAR_BIT - 2)) - 1) << 1) + 1;
1501
+ static constexpr I min_val = std::numeric_limits<I>::is_specialized ? (std::numeric_limits<I>::min)() : -max_val - 1;
1502
+
1503
+
1504
+ switch (arg.exponent())
1505
+ {
1506
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1507
+ *res = 0;
1508
+ return;
1509
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1510
+ BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1511
+ return;
1512
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1513
+ *res = max_val;
1514
+ if (arg.sign())
1515
+ *res = -*res;
1516
+ return;
1517
+ }
1518
+ using shift_type = typename std::conditional<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type;
1519
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type man(arg.bits());
1520
+ shift_type shift = (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - arg.exponent();
1521
+ if (shift > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)
1522
+ {
1523
+ *res = 0;
1524
+ return;
1525
+ }
1526
+ if (arg.sign() && (arg.compare(min_val) <= 0))
1527
+ {
1528
+ *res = min_val;
1529
+ return;
1530
+ }
1531
+ else if (!arg.sign() && (arg.compare(max_val) >= 0))
1532
+ {
1533
+ *res = max_val;
1534
+ return;
1535
+ }
1536
+
1537
+ if (shift < 0)
1538
+ {
1539
+ if (static_cast<int>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - static_cast<int>(shift) <= digits)
1540
+ {
1541
+ // We have more bits in long_long_type than the float, so it's OK to left shift:
1542
+ eval_convert_to(res, man);
1543
+ *res <<= -shift;
1544
+ }
1545
+ else
1546
+ {
1547
+ *res = (std::numeric_limits<I>::max)();
1548
+ return;
1549
+ }
1550
+ }
1551
+ else
1552
+ {
1553
+ eval_right_shift(man, static_cast<double_limb_type>(shift));
1554
+ eval_convert_to(res, man);
1555
+ }
1556
+ if (arg.sign())
1557
+ {
1558
+ *res = -*res;
1559
+ }
1560
+ }
1561
+
1562
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1563
+ inline void eval_convert_to(long long* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1564
+ {
1565
+ convert_to_signed_int(res, arg);
1566
+ }
1567
+
1568
+ #ifdef BOOST_HAS_INT128
1569
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1570
+ inline void eval_convert_to(int128_type* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1571
+ {
1572
+ convert_to_signed_int(res, arg);
1573
+ }
1574
+ #endif
1575
+
1576
+ template <class I, unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1577
+ inline void convert_to_unsigned_int(I* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1578
+ {
1579
+ static constexpr int digits = std::numeric_limits<I>::is_specialized ? std::numeric_limits<I>::digits : sizeof(I) * CHAR_BIT;
1580
+ static constexpr I max_val = std::numeric_limits<I>::is_specialized ? (std::numeric_limits<I>::max)() : ~static_cast<I>(0);
1581
+
1582
+ switch (arg.exponent())
1583
+ {
1584
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1585
+ *res = 0;
1586
+ return;
1587
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1588
+ BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
1589
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1590
+ *res = max_val;
1591
+ return;
1592
+ }
1593
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type man(arg.bits());
1594
+ using shift_type = typename std::conditional<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type;
1595
+ shift_type shift = (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - arg.exponent();
1596
+ if (shift > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)
1597
+ {
1598
+ *res = 0;
1599
+ return;
1600
+ }
1601
+ else if (shift < 0)
1602
+ {
1603
+ if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - shift <= digits)
1604
+ {
1605
+ // We have more bits in ulong_long_type than the float, so it's OK to left shift:
1606
+ eval_convert_to(res, man);
1607
+ *res <<= -shift;
1608
+ return;
1609
+ }
1610
+ *res = max_val;
1611
+ return;
1612
+ }
1613
+ eval_right_shift(man, shift);
1614
+ eval_convert_to(res, man);
1615
+ }
1616
+
1617
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1618
+ inline void eval_convert_to(unsigned long long* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1619
+ {
1620
+ convert_to_unsigned_int(res, arg);
1621
+ }
1622
+
1623
+ #ifdef BOOST_HAS_INT128
1624
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1625
+ inline void eval_convert_to(uint128_type* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1626
+ {
1627
+ convert_to_unsigned_int(res, arg);
1628
+ }
1629
+ #endif
1630
+
1631
+ template <class Float, unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1632
+ inline typename std::enable_if<std::is_floating_point<Float>::value>::type eval_convert_to(Float* res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& original_arg)
1633
+ {
1634
+ using conv_type = cpp_bin_float<std::numeric_limits<Float>::digits, digit_base_2, void, Exponent, MinE, MaxE>;
1635
+ using common_exp_type = typename std::common_type<typename conv_type::exponent_type, int>::type;
1636
+
1637
+ static constexpr int float_digits = boost::multiprecision::detail::is_float128<Float>::value ? 113 : std::numeric_limits<Float>::digits;
1638
+
1639
+ BOOST_MP_FLOAT128_USING using std::ldexp;
1640
+ //
1641
+ // Special cases first:
1642
+ //
1643
+ switch (original_arg.exponent())
1644
+ {
1645
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1646
+ *res = 0;
1647
+ if (original_arg.sign())
1648
+ *res = -*res;
1649
+ return;
1650
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1651
+ BOOST_IF_CONSTEXPR(boost::multiprecision::detail::is_float128<Float>::value)
1652
+ {
1653
+ *res = static_cast<Float>(std::numeric_limits<double>::quiet_NaN());
1654
+ }
1655
+ else
1656
+ {
1657
+ *res = std::numeric_limits<Float>::quiet_NaN();
1658
+ }
1659
+ return;
1660
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1661
+ BOOST_IF_CONSTEXPR(boost::multiprecision::detail::is_float128<Float>::value)
1662
+ {
1663
+ *res = static_cast<Float>((std::numeric_limits<double>::infinity)());
1664
+ }
1665
+ else
1666
+ {
1667
+ *res = (std::numeric_limits<Float>::infinity)();
1668
+ }
1669
+ if (original_arg.sign())
1670
+ *res = -*res;
1671
+ return;
1672
+ }
1673
+ //
1674
+ // Check for super large exponent that must be converted to infinity:
1675
+ //
1676
+ if (original_arg.exponent() > (boost::multiprecision::detail::is_float128<Float>::value ? 16384 : std::numeric_limits<Float>::max_exponent))
1677
+ {
1678
+ BOOST_IF_CONSTEXPR(boost::multiprecision::detail::is_float128<Float>::value)
1679
+ {
1680
+ *res = static_cast<Float>(std::numeric_limits<double>::infinity());
1681
+ }
1682
+ else
1683
+ {
1684
+ *res = std::numeric_limits<Float>::has_infinity ? std::numeric_limits<Float>::infinity() : (std::numeric_limits<Float>::max)();
1685
+ }
1686
+ if (original_arg.sign())
1687
+ *res = -*res;
1688
+ return;
1689
+ }
1690
+ //
1691
+ // Figure out how many digits we will have in our result,
1692
+ // allowing for a possibly denormalized result:
1693
+ //
1694
+ common_exp_type digits_to_round_to = float_digits;
1695
+ if (original_arg.exponent() < std::numeric_limits<Float>::min_exponent - 1)
1696
+ {
1697
+ common_exp_type diff = original_arg.exponent();
1698
+ diff -= boost::multiprecision::detail::is_float128<Float>::value ? -16382 : std::numeric_limits<Float>::min_exponent - 1;
1699
+ digits_to_round_to += diff;
1700
+ }
1701
+ if (digits_to_round_to < 0)
1702
+ {
1703
+ // Result must be zero:
1704
+ *res = 0;
1705
+ if (original_arg.sign())
1706
+ *res = -*res;
1707
+ return;
1708
+ }
1709
+ //
1710
+ // Perform rounding first, then afterwards extract the digits:
1711
+ //
1712
+ cpp_bin_float<static_cast<unsigned>(float_digits), digit_base_2, Allocator, Exponent, 0, 0> arg;
1713
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type bits(original_arg.bits());
1714
+ arg.exponent() = original_arg.exponent();
1715
+ copy_and_round(arg, bits, (std::ptrdiff_t)digits_to_round_to);
1716
+ common_exp_type e = arg.exponent();
1717
+ e -= static_cast<common_exp_type>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - 1;
1718
+ constexpr std::size_t limbs_needed = static_cast<std::size_t>(float_digits) / (sizeof(*arg.bits().limbs()) * CHAR_BIT) + (static_cast<std::size_t>(float_digits) % (sizeof(*arg.bits().limbs()) * CHAR_BIT) ? 1 : 0);
1719
+ std::size_t first_limb_needed = arg.bits().size() - limbs_needed;
1720
+ *res = 0;
1721
+ e += static_cast<common_exp_type>(first_limb_needed * sizeof(*arg.bits().limbs()) * CHAR_BIT);
1722
+ while (first_limb_needed < arg.bits().size())
1723
+ {
1724
+ *res += ldexp(static_cast<Float>(arg.bits().limbs()[first_limb_needed]), static_cast<int>(e));
1725
+ ++first_limb_needed;
1726
+ e += static_cast<common_exp_type>(sizeof(*arg.bits().limbs()) * CHAR_BIT);
1727
+ }
1728
+ if (original_arg.sign())
1729
+ *res = -*res;
1730
+ }
1731
+
1732
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1733
+ inline void eval_frexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg, Exponent* e)
1734
+ {
1735
+ switch (arg.exponent())
1736
+ {
1737
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1738
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1739
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1740
+ *e = 0;
1741
+ res = arg;
1742
+ return;
1743
+ }
1744
+ res = arg;
1745
+ *e = arg.exponent() + 1;
1746
+ res.exponent() = -1;
1747
+ }
1748
+
1749
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I>
1750
+ inline void eval_frexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg, I* pe)
1751
+ {
1752
+ Exponent e;
1753
+ eval_frexp(res, arg, &e);
1754
+ if ((e > (std::numeric_limits<I>::max)()) || (e < (std::numeric_limits<I>::min)()))
1755
+ {
1756
+ BOOST_MP_THROW_EXCEPTION(std::runtime_error("Exponent was outside of the range of the argument type to frexp."));
1757
+ }
1758
+ *pe = static_cast<I>(e);
1759
+ }
1760
+
1761
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1762
+ inline void eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg, Exponent e)
1763
+ {
1764
+ switch (arg.exponent())
1765
+ {
1766
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1767
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1768
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1769
+ res = arg;
1770
+ return;
1771
+ }
1772
+ if ((e > 0) && (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent - e < arg.exponent()))
1773
+ {
1774
+ // Overflow:
1775
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
1776
+ res.sign() = arg.sign();
1777
+ }
1778
+ else if ((e < 0) && (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent - e > arg.exponent()))
1779
+ {
1780
+ // Underflow:
1781
+ res = limb_type(0);
1782
+ }
1783
+ else
1784
+ {
1785
+ res = arg;
1786
+ res.exponent() += e;
1787
+ }
1788
+ }
1789
+
1790
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I>
1791
+ inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<I>::value>::type eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg, I e)
1792
+ {
1793
+ using si_type = typename boost::multiprecision::detail::make_signed<I>::type;
1794
+ if (e > static_cast<I>((std::numeric_limits<si_type>::max)()))
1795
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
1796
+ else
1797
+ eval_ldexp(res, arg, static_cast<si_type>(e));
1798
+ }
1799
+
1800
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class I>
1801
+ inline typename std::enable_if<boost::multiprecision::detail::is_signed<I>::value && boost::multiprecision::detail::is_integral<I>::value>::type eval_ldexp(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg, I e)
1802
+ {
1803
+ if ((e > (std::numeric_limits<Exponent>::max)()) || (e < (std::numeric_limits<Exponent>::min)()))
1804
+ {
1805
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::infinity().backend();
1806
+ if (e < 0)
1807
+ res.negate();
1808
+ }
1809
+ else
1810
+ eval_ldexp(res, arg, static_cast<Exponent>(e));
1811
+ }
1812
+
1813
+ /*
1814
+ * Sign manipulation
1815
+ */
1816
+
1817
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1818
+ unsigned Digits2, digit_base_type DigitBase2, class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
1819
+ inline void eval_abs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits2, DigitBase2, Allocator2, Exponent2, MinE2, MaxE2>& arg)
1820
+ {
1821
+ res = arg;
1822
+ res.sign() = false;
1823
+ }
1824
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1825
+ inline void eval_abs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1826
+ {
1827
+ res = arg;
1828
+ res.sign() = false;
1829
+ }
1830
+
1831
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE,
1832
+ unsigned Digits2, digit_base_type DigitBase2, class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
1833
+ inline void eval_fabs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits2, DigitBase2, Allocator2, Exponent2, MinE2, MaxE2>& arg)
1834
+ {
1835
+ res = arg;
1836
+ res.sign() = false;
1837
+ }
1838
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1839
+ inline void eval_fabs(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1840
+ {
1841
+ res = arg;
1842
+ res.sign() = false;
1843
+ }
1844
+
1845
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1846
+ inline int eval_fpclassify(const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1847
+ {
1848
+ switch (arg.exponent())
1849
+ {
1850
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1851
+ return FP_ZERO;
1852
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1853
+ return FP_INFINITE;
1854
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1855
+ return FP_NAN;
1856
+ }
1857
+ return FP_NORMAL;
1858
+ }
1859
+
1860
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1861
+ inline void eval_sqrt(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1862
+ {
1863
+ using default_ops::eval_bit_test;
1864
+ using default_ops::eval_increment;
1865
+ using default_ops::eval_integer_sqrt;
1866
+ switch (arg.exponent())
1867
+ {
1868
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1869
+ errno = EDOM;
1870
+ // fallthrough...
1871
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1872
+ res = arg;
1873
+ return;
1874
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1875
+ if (arg.sign())
1876
+ {
1877
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1878
+ errno = EDOM;
1879
+ }
1880
+ else
1881
+ res = arg;
1882
+ return;
1883
+ }
1884
+ if (arg.sign())
1885
+ {
1886
+ res = std::numeric_limits<number<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > >::quiet_NaN().backend();
1887
+ errno = EDOM;
1888
+ return;
1889
+ }
1890
+
1891
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::double_rep_type t(arg.bits()), r, s;
1892
+ eval_left_shift(t, arg.exponent() & 1 ? cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count : cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1);
1893
+ eval_integer_sqrt(s, r, t);
1894
+
1895
+ if (!eval_bit_test(s, cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count))
1896
+ {
1897
+ // We have exactly the right number of cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count in the result, round as required:
1898
+ if (s.compare(r) < 0)
1899
+ {
1900
+ eval_increment(s);
1901
+ }
1902
+ }
1903
+ typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type ae = arg.exponent();
1904
+ res.exponent() = ae / 2;
1905
+ res.sign() = false;
1906
+ if ((ae & 1) && (ae < 0))
1907
+ --res.exponent();
1908
+ copy_and_round(res, s);
1909
+ }
1910
+
1911
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1912
+ inline void eval_floor(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1913
+ {
1914
+ using default_ops::eval_increment;
1915
+ switch (arg.exponent())
1916
+ {
1917
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1918
+ errno = EDOM;
1919
+ // fallthrough...
1920
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1921
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1922
+ res = arg;
1923
+ return;
1924
+ }
1925
+ using shift_type = typename std::conditional<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type;
1926
+ shift_type shift =
1927
+ (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - arg.exponent() - 1;
1928
+ if ((arg.exponent() > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) || (shift <= 0))
1929
+ {
1930
+ // Either arg is already an integer, or a special value:
1931
+ res = arg;
1932
+ return;
1933
+ }
1934
+ if (shift >= (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
1935
+ {
1936
+ res = static_cast<signed_limb_type>(arg.sign() ? -1 : 0);
1937
+ return;
1938
+ }
1939
+ bool fractional = (shift_type)eval_lsb(arg.bits()) < shift;
1940
+ res = arg;
1941
+ eval_right_shift(res.bits(), static_cast<double_limb_type>(shift));
1942
+ if (fractional && res.sign())
1943
+ {
1944
+ eval_increment(res.bits());
1945
+
1946
+ const std::ptrdiff_t shift_check =
1947
+ static_cast<std::ptrdiff_t>(static_cast<std::ptrdiff_t>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - 1 - static_cast<std::ptrdiff_t>(shift));
1948
+
1949
+ if (static_cast<std::ptrdiff_t>(eval_msb(res.bits())) != shift_check)
1950
+ {
1951
+ // Must have extended result by one bit in the increment:
1952
+ --shift;
1953
+ ++res.exponent();
1954
+ }
1955
+ }
1956
+ eval_left_shift(res.bits(), static_cast<double_limb_type>(shift));
1957
+ }
1958
+
1959
+ template <unsigned Digits, digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE>
1960
+ inline void eval_ceil(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& res, const cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>& arg)
1961
+ {
1962
+ using default_ops::eval_increment;
1963
+ switch (arg.exponent())
1964
+ {
1965
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
1966
+ errno = EDOM;
1967
+ // fallthrough...
1968
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_zero:
1969
+ case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
1970
+ res = arg;
1971
+ return;
1972
+ }
1973
+ using shift_type = typename std::conditional<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type;
1974
+ shift_type shift = (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - arg.exponent() - 1;
1975
+ if ((arg.exponent() > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent) || (shift <= 0))
1976
+ {
1977
+ // Either arg is already an integer, or a special value:
1978
+ res = arg;
1979
+ return;
1980
+ }
1981
+ if (shift >= (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count)
1982
+ {
1983
+ bool s = arg.sign(); // takes care of signed zeros
1984
+ res = static_cast<signed_limb_type>(arg.sign() ? 0 : 1);
1985
+ res.sign() = s;
1986
+ return;
1987
+ }
1988
+ bool fractional = (shift_type)eval_lsb(arg.bits()) < shift;
1989
+ res = arg;
1990
+ eval_right_shift(res.bits(), shift);
1991
+ if (fractional && !res.sign())
1992
+ {
1993
+ eval_increment(res.bits());
1994
+ if ((std::ptrdiff_t)eval_msb(res.bits()) != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - shift)
1995
+ {
1996
+ // Must have extended result by one bit in the increment:
1997
+ --shift;
1998
+ ++res.exponent();
1999
+ }
2000
+ }
2001
+ eval_left_shift(res.bits(), shift);
2002
+ }
2003
+
2004
+ template <unsigned D1, backends::digit_base_type B1, class A1, class E1, E1 M1, E1 M2>
2005
+ int eval_signbit(const cpp_bin_float<D1, B1, A1, E1, M1, M2>& val)
2006
+ {
2007
+ return val.sign();
2008
+ }
2009
+
2010
+ template <unsigned D1, backends::digit_base_type B1, class A1, class E1, E1 M1, E1 M2>
2011
+ inline std::size_t hash_value(const cpp_bin_float<D1, B1, A1, E1, M1, M2>& val)
2012
+ {
2013
+ std::size_t result = hash_value(val.bits());
2014
+ boost::multiprecision::detail::hash_combine(result, val.exponent(), val.sign());
2015
+ return result;
2016
+ }
2017
+
2018
+ } // namespace backends
2019
+
2020
+ namespace detail {
2021
+
2022
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinExponent, Exponent MaxExponent>
2023
+ struct transcendental_reduction_type<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinExponent, MaxExponent> >
2024
+ {
2025
+ //
2026
+ // The type used for trigonometric reduction needs 3 times the precision of the base type.
2027
+ // This is double the precision of the original type, plus the largest exponent supported.
2028
+ // As a practical measure the largest argument supported is 1/eps, as supporting larger
2029
+ // arguments requires the division of argument by PI/2 to also be done at higher precision,
2030
+ // otherwise the result (an integer) can not be represented exactly.
2031
+ //
2032
+ // See ARGUMENT REDUCTION FOR HUGE ARGUMENTS. K C Ng.
2033
+ //
2034
+ using type = boost::multiprecision::backends::cpp_bin_float<
2035
+ boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinExponent, MaxExponent>::bit_count * 3,
2036
+ boost::multiprecision::backends::digit_base_2,
2037
+ Allocator, Exponent, MinExponent, MaxExponent>;
2038
+ };
2039
+ #ifdef BOOST_HAS_INT128
2040
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinExponent, Exponent MaxExponent>
2041
+ struct is_convertible_arithmetic<int128_type, boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinExponent, MaxExponent> > : public std::true_type
2042
+ {};
2043
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinExponent, Exponent MaxExponent>
2044
+ struct is_convertible_arithmetic<uint128_type, boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinExponent, MaxExponent> > : public std::true_type
2045
+ {};
2046
+ #endif
2047
+
2048
+ } // namespace detail
2049
+
2050
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Exponent, Exponent MinE, Exponent MaxE, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
2051
+ inline boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>
2052
+ copysign BOOST_PREVENT_MACRO_SUBSTITUTION(
2053
+ const boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>& a,
2054
+ const boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>& b)
2055
+ {
2056
+ boost::multiprecision::number<boost::multiprecision::backends::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> res(a);
2057
+ res.backend().sign() = b.backend().sign();
2058
+ return res;
2059
+ }
2060
+
2061
+ template <unsigned Digits, backends::digit_base_type DigitBase, class Exponent, Exponent MinE, Exponent MaxE, class Allocator>
2062
+ struct number_category<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE> > : public std::integral_constant<int, boost::multiprecision::number_kind_floating_point>
2063
+ {};
2064
+
2065
+ template <unsigned Digits, backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, class Allocator2, class Exponent2, Exponent MinE2, Exponent MaxE2>
2066
+ struct is_equivalent_number_type<cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, cpp_bin_float<Digits, DigitBase, Allocator2, Exponent2, MinE2, MaxE2> >
2067
+ : public std::integral_constant<bool, true> {};
2068
+
2069
+ } // namespace multiprecision
2070
+
2071
+ namespace math {
2072
+
2073
+ using boost::multiprecision::copysign;
2074
+ using boost::multiprecision::signbit;
2075
+
2076
+ } // namespace math
2077
+
2078
+ } // namespace boost
2079
+
2080
+ #include <boost/multiprecision/cpp_bin_float/io.hpp>
2081
+ #include <boost/multiprecision/cpp_bin_float/transcendental.hpp>
2082
+
2083
+ namespace std {
2084
+
2085
+ //
2086
+ // numeric_limits [partial] specializations for the types declared in this header:
2087
+ //
2088
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2089
+ class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >
2090
+ {
2091
+ using number_type = boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates>;
2092
+
2093
+ private:
2094
+ //
2095
+ // Functions to calculate cached values stored in static values:
2096
+ //
2097
+ static number_type get_min()
2098
+ {
2099
+ using ui_type = typename std::tuple_element<0, typename number_type::backend_type::unsigned_types>::type;
2100
+ number_type value(ui_type(1u));
2101
+ value.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent;
2102
+ return value;
2103
+ }
2104
+ #ifdef BOOST_MSVC
2105
+ #pragma warning(push)
2106
+ #pragma warning(disable : 4127) // conditional expression is constant
2107
+ #endif
2108
+ static number_type get_max()
2109
+ {
2110
+ number_type value;
2111
+ BOOST_IF_CONSTEXPR(std::is_void<Allocator>::value)
2112
+ eval_complement(value.backend().bits(), value.backend().bits());
2113
+ else
2114
+ {
2115
+ // We jump through hoops here using the backend type directly just to keep VC12 happy
2116
+ // (ie compiler workaround, for very strange compiler bug):
2117
+ using boost::multiprecision::default_ops::eval_add;
2118
+ using boost::multiprecision::default_ops::eval_decrement;
2119
+ using boost::multiprecision::default_ops::eval_left_shift;
2120
+ using int_backend_type = typename number_type::backend_type::rep_type;
2121
+ using ui_type = typename std::tuple_element<0, typename int_backend_type::unsigned_types>::type;
2122
+ int_backend_type i;
2123
+ i = ui_type(1u);
2124
+ eval_left_shift(i, boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1);
2125
+ int_backend_type j(i);
2126
+ eval_decrement(i);
2127
+ eval_add(j, i);
2128
+ value.backend().bits() = j;
2129
+ }
2130
+ value.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent;
2131
+ return value;
2132
+ }
2133
+ #ifdef BOOST_MSVC
2134
+ #pragma warning(pop)
2135
+ #endif
2136
+ static number_type get_epsilon()
2137
+ {
2138
+ using ui_type = typename std::tuple_element<0, typename number_type::backend_type::unsigned_types>::type;
2139
+ number_type value(ui_type(1u));
2140
+ return ldexp(value, 1 - static_cast<int>(digits));
2141
+ }
2142
+ // What value should this be????
2143
+ static number_type get_round_error()
2144
+ {
2145
+ // returns 0.5
2146
+ return ldexp(number_type(1u), -1);
2147
+ }
2148
+ static number_type get_infinity()
2149
+ {
2150
+ number_type value;
2151
+ value.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity;
2152
+ return value;
2153
+ }
2154
+ static number_type get_quiet_NaN()
2155
+ {
2156
+ number_type value;
2157
+ value.backend().exponent() = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan;
2158
+ return value;
2159
+ }
2160
+
2161
+ public:
2162
+ static constexpr bool is_specialized = true;
2163
+ static number_type(min)()
2164
+ {
2165
+ // C++11 thread safe static initialization:
2166
+ static number_type value = get_min();
2167
+ return value;
2168
+ }
2169
+ static number_type(max)()
2170
+ {
2171
+ // C++11 thread safe static initialization:
2172
+ static number_type value = get_max();
2173
+ return value;
2174
+ }
2175
+ static constexpr number_type lowest()
2176
+ {
2177
+ return -(max)();
2178
+ }
2179
+ static constexpr int digits = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count;
2180
+ static constexpr int digits10 = boost::multiprecision::detail::calc_digits10<static_cast<unsigned>(digits)>::value;
2181
+ // Is this really correct???
2182
+ static constexpr int max_digits10 = boost::multiprecision::detail::calc_max_digits10<static_cast<unsigned>(digits)>::value;
2183
+ static constexpr bool is_signed = true;
2184
+ static constexpr bool is_integer = false;
2185
+ static constexpr bool is_exact = false;
2186
+ static constexpr int radix = 2;
2187
+ static number_type epsilon()
2188
+ {
2189
+ // C++11 thread safe static initialization:
2190
+ static number_type value = get_epsilon();
2191
+ return value;
2192
+ }
2193
+ // What value should this be????
2194
+ static number_type round_error()
2195
+ {
2196
+ // returns 0.5
2197
+ // C++11 thread safe static initialization:
2198
+ static number_type value = get_round_error();
2199
+ return value;
2200
+ }
2201
+ static constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type min_exponent = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::min_exponent;
2202
+ static constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type min_exponent10 = (min_exponent / 1000) * 301L;
2203
+ static constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type max_exponent = boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::max_exponent;
2204
+ static constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type max_exponent10 = (max_exponent / 1000) * 301L;
2205
+ static constexpr bool has_infinity = true;
2206
+ static constexpr bool has_quiet_NaN = true;
2207
+ static constexpr bool has_signaling_NaN = false;
2208
+ #ifdef _MSC_VER
2209
+ #pragma warning(push)
2210
+ #pragma warning(disable:4996)
2211
+ #endif
2212
+ static constexpr float_denorm_style has_denorm = denorm_absent;
2213
+ #ifdef _MSC_VER
2214
+ #pragma warning(pop)
2215
+ #endif
2216
+ static constexpr bool has_denorm_loss = false;
2217
+ static number_type infinity()
2218
+ {
2219
+ // C++11 thread safe static initialization:
2220
+ static number_type value = get_infinity();
2221
+ return value;
2222
+ }
2223
+ static number_type quiet_NaN()
2224
+ {
2225
+ // C++11 thread safe static initialization:
2226
+ static number_type value = get_quiet_NaN();
2227
+ return value;
2228
+ }
2229
+ static constexpr number_type signaling_NaN()
2230
+ {
2231
+ return number_type(0);
2232
+ }
2233
+ static constexpr number_type denorm_min() { return get_min(); }
2234
+ static constexpr bool is_iec559 = false;
2235
+ static constexpr bool is_bounded = true;
2236
+ static constexpr bool is_modulo = false;
2237
+ static constexpr bool traps = true;
2238
+ static constexpr bool tinyness_before = false;
2239
+ static constexpr float_round_style round_style = round_to_nearest;
2240
+ };
2241
+
2242
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2243
+ constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::digits;
2244
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2245
+ constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::digits10;
2246
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2247
+ constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_digits10;
2248
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2249
+ constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_signed;
2250
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2251
+ constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_integer;
2252
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2253
+ constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_exact;
2254
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2255
+ constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::radix;
2256
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2257
+ constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::min_exponent;
2258
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2259
+ constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::min_exponent10;
2260
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2261
+ constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_exponent;
2262
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2263
+ constexpr typename boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::max_exponent10;
2264
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2265
+ constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_infinity;
2266
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2267
+ constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_quiet_NaN;
2268
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2269
+ constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_signaling_NaN;
2270
+ #ifdef _MSC_VER
2271
+ #pragma warning(push)
2272
+ #pragma warning(disable:4996)
2273
+ #endif
2274
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2275
+ constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_denorm;
2276
+ #ifdef _MSC_VER
2277
+ #pragma warning(pop)
2278
+ #endif
2279
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2280
+ constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::has_denorm_loss;
2281
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2282
+ constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_iec559;
2283
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2284
+ constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_bounded;
2285
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2286
+ constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::is_modulo;
2287
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2288
+ constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::traps;
2289
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2290
+ constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::tinyness_before;
2291
+ template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinE, Exponent MaxE, boost::multiprecision::expression_template_option ExpressionTemplates>
2292
+ constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>, ExpressionTemplates> >::round_style;
2293
+
2294
+
2295
+ } // namespace std
2296
+
2297
+ #endif