mqt-core 3.3.2__cp314-cp314t-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.
- mqt/core/__init__.py +89 -0
- mqt/core/__main__.py +55 -0
- mqt/core/_commands.py +52 -0
- mqt/core/_compat/__init__.py +11 -0
- mqt/core/_compat/typing.py +29 -0
- mqt/core/_version.py +34 -0
- mqt/core/_version.pyi +12 -0
- mqt/core/bin/mqt-core-algorithms.dll +0 -0
- mqt/core/bin/mqt-core-circuit-optimizer.dll +0 -0
- mqt/core/bin/mqt-core-dd.dll +0 -0
- mqt/core/bin/mqt-core-ds.dll +0 -0
- mqt/core/bin/mqt-core-fomac.dll +0 -0
- mqt/core/bin/mqt-core-ir.dll +0 -0
- mqt/core/bin/mqt-core-na-fomac.dll +0 -0
- mqt/core/bin/mqt-core-na.dll +0 -0
- mqt/core/bin/mqt-core-qasm.dll +0 -0
- mqt/core/bin/mqt-core-qdmi-driver.dll +0 -0
- mqt/core/bin/mqt-core-qdmi-na-device.dll +0 -0
- mqt/core/bin/mqt-core-zx.dll +0 -0
- mqt/core/dd.cp314t-win_amd64.pyd +0 -0
- mqt/core/dd.pyi +1016 -0
- mqt/core/dd_evaluation.py +368 -0
- mqt/core/fomac.cp314t-win_amd64.pyd +0 -0
- mqt/core/fomac.pyi +125 -0
- mqt/core/include/mqt-core/algorithms/BernsteinVazirani.hpp +39 -0
- mqt/core/include/mqt-core/algorithms/GHZState.hpp +18 -0
- mqt/core/include/mqt-core/algorithms/Grover.hpp +33 -0
- mqt/core/include/mqt-core/algorithms/QFT.hpp +21 -0
- mqt/core/include/mqt-core/algorithms/QPE.hpp +30 -0
- mqt/core/include/mqt-core/algorithms/RandomCliffordCircuit.hpp +22 -0
- mqt/core/include/mqt-core/algorithms/StatePreparation.hpp +43 -0
- mqt/core/include/mqt-core/algorithms/WState.hpp +18 -0
- mqt/core/include/mqt-core/algorithms/mqt_core_algorithms_export.h +43 -0
- mqt/core/include/mqt-core/boost/config/abi/borland_prefix.hpp +27 -0
- mqt/core/include/mqt-core/boost/config/abi/borland_suffix.hpp +12 -0
- mqt/core/include/mqt-core/boost/config/abi/msvc_prefix.hpp +22 -0
- mqt/core/include/mqt-core/boost/config/abi/msvc_suffix.hpp +8 -0
- mqt/core/include/mqt-core/boost/config/abi_prefix.hpp +25 -0
- mqt/core/include/mqt-core/boost/config/abi_suffix.hpp +25 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx03.hpp +211 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx11.hpp +212 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx14.hpp +47 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx17.hpp +65 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx20.hpp +59 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx23.hpp +41 -0
- mqt/core/include/mqt-core/boost/config/assert_cxx98.hpp +23 -0
- mqt/core/include/mqt-core/boost/config/auto_link.hpp +525 -0
- mqt/core/include/mqt-core/boost/config/compiler/borland.hpp +342 -0
- mqt/core/include/mqt-core/boost/config/compiler/clang.hpp +370 -0
- mqt/core/include/mqt-core/boost/config/compiler/clang_version.hpp +89 -0
- mqt/core/include/mqt-core/boost/config/compiler/codegear.hpp +389 -0
- mqt/core/include/mqt-core/boost/config/compiler/comeau.hpp +59 -0
- mqt/core/include/mqt-core/boost/config/compiler/common_edg.hpp +185 -0
- mqt/core/include/mqt-core/boost/config/compiler/compaq_cxx.hpp +19 -0
- mqt/core/include/mqt-core/boost/config/compiler/cray.hpp +446 -0
- mqt/core/include/mqt-core/boost/config/compiler/diab.hpp +26 -0
- mqt/core/include/mqt-core/boost/config/compiler/digitalmars.hpp +146 -0
- mqt/core/include/mqt-core/boost/config/compiler/gcc.hpp +386 -0
- mqt/core/include/mqt-core/boost/config/compiler/gcc_xml.hpp +115 -0
- mqt/core/include/mqt-core/boost/config/compiler/greenhills.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/compiler/hp_acc.hpp +153 -0
- mqt/core/include/mqt-core/boost/config/compiler/intel.hpp +577 -0
- mqt/core/include/mqt-core/boost/config/compiler/kai.hpp +33 -0
- mqt/core/include/mqt-core/boost/config/compiler/metrowerks.hpp +201 -0
- mqt/core/include/mqt-core/boost/config/compiler/mpw.hpp +143 -0
- mqt/core/include/mqt-core/boost/config/compiler/nvcc.hpp +64 -0
- mqt/core/include/mqt-core/boost/config/compiler/pathscale.hpp +141 -0
- mqt/core/include/mqt-core/boost/config/compiler/pgi.hpp +23 -0
- mqt/core/include/mqt-core/boost/config/compiler/sgi_mipspro.hpp +29 -0
- mqt/core/include/mqt-core/boost/config/compiler/sunpro_cc.hpp +225 -0
- mqt/core/include/mqt-core/boost/config/compiler/vacpp.hpp +189 -0
- mqt/core/include/mqt-core/boost/config/compiler/visualc.hpp +398 -0
- mqt/core/include/mqt-core/boost/config/compiler/xlcpp.hpp +303 -0
- mqt/core/include/mqt-core/boost/config/compiler/xlcpp_zos.hpp +174 -0
- mqt/core/include/mqt-core/boost/config/detail/cxx_composite.hpp +218 -0
- mqt/core/include/mqt-core/boost/config/detail/posix_features.hpp +95 -0
- mqt/core/include/mqt-core/boost/config/detail/select_compiler_config.hpp +157 -0
- mqt/core/include/mqt-core/boost/config/detail/select_platform_config.hpp +147 -0
- mqt/core/include/mqt-core/boost/config/detail/select_stdlib_config.hpp +121 -0
- mqt/core/include/mqt-core/boost/config/detail/suffix.hpp +1334 -0
- mqt/core/include/mqt-core/boost/config/header_deprecated.hpp +26 -0
- mqt/core/include/mqt-core/boost/config/helper_macros.hpp +37 -0
- mqt/core/include/mqt-core/boost/config/no_tr1/cmath.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/no_tr1/complex.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/no_tr1/functional.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/no_tr1/memory.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/no_tr1/utility.hpp +28 -0
- mqt/core/include/mqt-core/boost/config/platform/aix.hpp +33 -0
- mqt/core/include/mqt-core/boost/config/platform/amigaos.hpp +15 -0
- mqt/core/include/mqt-core/boost/config/platform/beos.hpp +26 -0
- mqt/core/include/mqt-core/boost/config/platform/bsd.hpp +83 -0
- mqt/core/include/mqt-core/boost/config/platform/cloudabi.hpp +18 -0
- mqt/core/include/mqt-core/boost/config/platform/cray.hpp +18 -0
- mqt/core/include/mqt-core/boost/config/platform/cygwin.hpp +71 -0
- mqt/core/include/mqt-core/boost/config/platform/haiku.hpp +31 -0
- mqt/core/include/mqt-core/boost/config/platform/hpux.hpp +87 -0
- mqt/core/include/mqt-core/boost/config/platform/irix.hpp +31 -0
- mqt/core/include/mqt-core/boost/config/platform/linux.hpp +106 -0
- mqt/core/include/mqt-core/boost/config/platform/macos.hpp +87 -0
- mqt/core/include/mqt-core/boost/config/platform/qnxnto.hpp +31 -0
- mqt/core/include/mqt-core/boost/config/platform/solaris.hpp +31 -0
- mqt/core/include/mqt-core/boost/config/platform/symbian.hpp +97 -0
- mqt/core/include/mqt-core/boost/config/platform/vms.hpp +25 -0
- mqt/core/include/mqt-core/boost/config/platform/vxworks.hpp +422 -0
- mqt/core/include/mqt-core/boost/config/platform/wasm.hpp +23 -0
- mqt/core/include/mqt-core/boost/config/platform/win32.hpp +90 -0
- mqt/core/include/mqt-core/boost/config/platform/zos.hpp +32 -0
- mqt/core/include/mqt-core/boost/config/pragma_message.hpp +31 -0
- mqt/core/include/mqt-core/boost/config/requires_threads.hpp +92 -0
- mqt/core/include/mqt-core/boost/config/stdlib/dinkumware.hpp +324 -0
- mqt/core/include/mqt-core/boost/config/stdlib/libcomo.hpp +93 -0
- mqt/core/include/mqt-core/boost/config/stdlib/libcpp.hpp +180 -0
- mqt/core/include/mqt-core/boost/config/stdlib/libstdcpp3.hpp +482 -0
- mqt/core/include/mqt-core/boost/config/stdlib/modena.hpp +79 -0
- mqt/core/include/mqt-core/boost/config/stdlib/msl.hpp +98 -0
- mqt/core/include/mqt-core/boost/config/stdlib/roguewave.hpp +208 -0
- mqt/core/include/mqt-core/boost/config/stdlib/sgi.hpp +168 -0
- mqt/core/include/mqt-core/boost/config/stdlib/stlport.hpp +258 -0
- mqt/core/include/mqt-core/boost/config/stdlib/vacpp.hpp +74 -0
- mqt/core/include/mqt-core/boost/config/stdlib/xlcpp_zos.hpp +61 -0
- mqt/core/include/mqt-core/boost/config/user.hpp +133 -0
- mqt/core/include/mqt-core/boost/config/warning_disable.hpp +47 -0
- mqt/core/include/mqt-core/boost/config/workaround.hpp +305 -0
- mqt/core/include/mqt-core/boost/config.hpp +67 -0
- mqt/core/include/mqt-core/boost/cstdint.hpp +556 -0
- mqt/core/include/mqt-core/boost/cxx11_char_types.hpp +70 -0
- mqt/core/include/mqt-core/boost/detail/workaround.hpp +10 -0
- mqt/core/include/mqt-core/boost/limits.hpp +146 -0
- mqt/core/include/mqt-core/boost/multiprecision/complex128.hpp +24 -0
- mqt/core/include/mqt-core/boost/multiprecision/complex_adaptor.hpp +1046 -0
- mqt/core/include/mqt-core/boost/multiprecision/concepts/mp_number_archetypes.hpp +257 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float/io.hpp +698 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float/transcendental.hpp +157 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_bin_float.hpp +2297 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_complex.hpp +12 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_dec_float.hpp +3690 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/add.hpp +368 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/add_unsigned.hpp +387 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/bitwise.hpp +889 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/checked.hpp +178 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/comparison.hpp +374 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/cpp_int_config.hpp +161 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/divide.hpp +703 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/import_export.hpp +248 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/intel_intrinsics.hpp +138 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/limits.hpp +282 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/literals.hpp +295 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/misc.hpp +1457 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/multiply.hpp +848 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/serialize.hpp +211 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int/value_pack.hpp +42 -0
- mqt/core/include/mqt-core/boost/multiprecision/cpp_int.hpp +2360 -0
- mqt/core/include/mqt-core/boost/multiprecision/debug_adaptor.hpp +760 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/assert.hpp +29 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/atomic.hpp +62 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/bitscan.hpp +317 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/check_cpp11_config.hpp +64 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/constexpr.hpp +88 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/default_ops.hpp +4052 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/digits.hpp +49 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/dynamic_array.hpp +44 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/empty_value.hpp +87 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/endian.hpp +35 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/et_ops.hpp +1831 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/float128_functions.hpp +95 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/float_string_cvt.hpp +333 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/fpclassify.hpp +101 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/functions/constants.hpp +288 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/functions/pow.hpp +905 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/functions/trig.hpp +1058 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/functions/trunc.hpp +82 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/generic_interconvert.hpp +687 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/hash.hpp +56 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/integer_ops.hpp +474 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/itos.hpp +39 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/min_max.hpp +106 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/no_et_ops.hpp +661 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/no_exceptions_support.hpp +55 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/number_base.hpp +1656 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/number_compare.hpp +848 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/precision.hpp +313 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/rebind.hpp +19 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/standalone_config.hpp +148 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/static_array.hpp +42 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/string_helpers.hpp +48 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/tables.hpp +80 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/ublas_interop.hpp +75 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/uniform_int_distribution.hpp +212 -0
- mqt/core/include/mqt-core/boost/multiprecision/detail/utype_helper.hpp +374 -0
- mqt/core/include/mqt-core/boost/multiprecision/eigen.hpp +248 -0
- mqt/core/include/mqt-core/boost/multiprecision/float128.hpp +920 -0
- mqt/core/include/mqt-core/boost/multiprecision/fwd.hpp +268 -0
- mqt/core/include/mqt-core/boost/multiprecision/gmp.hpp +4060 -0
- mqt/core/include/mqt-core/boost/multiprecision/integer.hpp +363 -0
- mqt/core/include/mqt-core/boost/multiprecision/logged_adaptor.hpp +834 -0
- mqt/core/include/mqt-core/boost/multiprecision/miller_rabin.hpp +221 -0
- mqt/core/include/mqt-core/boost/multiprecision/mpc.hpp +1721 -0
- mqt/core/include/mqt-core/boost/multiprecision/mpfi.hpp +2559 -0
- mqt/core/include/mqt-core/boost/multiprecision/mpfr.hpp +3644 -0
- mqt/core/include/mqt-core/boost/multiprecision/number.hpp +2500 -0
- mqt/core/include/mqt-core/boost/multiprecision/random.hpp +23 -0
- mqt/core/include/mqt-core/boost/multiprecision/rational_adaptor.hpp +1289 -0
- mqt/core/include/mqt-core/boost/multiprecision/tommath.hpp +1034 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/explicit_conversion.hpp +67 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/extract_exponent_type.hpp +28 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_backend.hpp +91 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_byte_container.hpp +51 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_complex.hpp +22 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_convertible_arithmetic.hpp +51 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_restricted_conversion.hpp +47 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/is_variable_precision.hpp +25 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/max_digits10.hpp +79 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/std_integer_traits.hpp +90 -0
- mqt/core/include/mqt-core/boost/multiprecision/traits/transcendental_reduction_type.hpp +21 -0
- mqt/core/include/mqt-core/boost/version.hpp +32 -0
- mqt/core/include/mqt-core/circuit_optimizer/CircuitOptimizer.hpp +119 -0
- mqt/core/include/mqt-core/circuit_optimizer/mqt_core_circuit_optimizer_export.h +43 -0
- mqt/core/include/mqt-core/datastructures/DirectedAcyclicGraph.hpp +117 -0
- mqt/core/include/mqt-core/datastructures/DirectedGraph.hpp +158 -0
- mqt/core/include/mqt-core/datastructures/DisjointSet.hpp +50 -0
- mqt/core/include/mqt-core/datastructures/Layer.hpp +172 -0
- mqt/core/include/mqt-core/datastructures/SymmetricMatrix.hpp +57 -0
- mqt/core/include/mqt-core/datastructures/UndirectedGraph.hpp +227 -0
- mqt/core/include/mqt-core/datastructures/mqt_core_ds_export.h +43 -0
- mqt/core/include/mqt-core/dd/Approximation.hpp +45 -0
- mqt/core/include/mqt-core/dd/CachedEdge.hpp +174 -0
- mqt/core/include/mqt-core/dd/Complex.hpp +165 -0
- mqt/core/include/mqt-core/dd/ComplexNumbers.hpp +150 -0
- mqt/core/include/mqt-core/dd/ComplexValue.hpp +184 -0
- mqt/core/include/mqt-core/dd/ComputeTable.hpp +183 -0
- mqt/core/include/mqt-core/dd/DDDefinitions.hpp +139 -0
- mqt/core/include/mqt-core/dd/DDpackageConfig.hpp +104 -0
- mqt/core/include/mqt-core/dd/DensityNoiseTable.hpp +114 -0
- mqt/core/include/mqt-core/dd/Edge.hpp +416 -0
- mqt/core/include/mqt-core/dd/Export.hpp +438 -0
- mqt/core/include/mqt-core/dd/FunctionalityConstruction.hpp +75 -0
- mqt/core/include/mqt-core/dd/GateMatrixDefinitions.hpp +43 -0
- mqt/core/include/mqt-core/dd/LinkedListBase.hpp +45 -0
- mqt/core/include/mqt-core/dd/MemoryManager.hpp +193 -0
- mqt/core/include/mqt-core/dd/Node.hpp +223 -0
- mqt/core/include/mqt-core/dd/NoiseFunctionality.hpp +144 -0
- mqt/core/include/mqt-core/dd/Operations.hpp +306 -0
- mqt/core/include/mqt-core/dd/Package.hpp +2036 -0
- mqt/core/include/mqt-core/dd/Package_fwd.hpp +22 -0
- mqt/core/include/mqt-core/dd/RealNumber.hpp +255 -0
- mqt/core/include/mqt-core/dd/RealNumberUniqueTable.hpp +217 -0
- mqt/core/include/mqt-core/dd/Simulation.hpp +98 -0
- mqt/core/include/mqt-core/dd/StateGeneration.hpp +143 -0
- mqt/core/include/mqt-core/dd/StochasticNoiseOperationTable.hpp +88 -0
- mqt/core/include/mqt-core/dd/UnaryComputeTable.hpp +121 -0
- mqt/core/include/mqt-core/dd/UniqueTable.hpp +243 -0
- mqt/core/include/mqt-core/dd/mqt_core_dd_export.h +43 -0
- mqt/core/include/mqt-core/dd/statistics/MemoryManagerStatistics.hpp +84 -0
- mqt/core/include/mqt-core/dd/statistics/PackageStatistics.hpp +55 -0
- mqt/core/include/mqt-core/dd/statistics/Statistics.hpp +48 -0
- mqt/core/include/mqt-core/dd/statistics/TableStatistics.hpp +79 -0
- mqt/core/include/mqt-core/dd/statistics/UniqueTableStatistics.hpp +31 -0
- mqt/core/include/mqt-core/fomac/FoMaC.hpp +568 -0
- mqt/core/include/mqt-core/ir/Definitions.hpp +108 -0
- mqt/core/include/mqt-core/ir/Permutation.hpp +213 -0
- mqt/core/include/mqt-core/ir/QuantumComputation.hpp +596 -0
- mqt/core/include/mqt-core/ir/Register.hpp +125 -0
- mqt/core/include/mqt-core/ir/mqt_core_ir_export.h +43 -0
- mqt/core/include/mqt-core/ir/operations/AodOperation.hpp +92 -0
- mqt/core/include/mqt-core/ir/operations/CompoundOperation.hpp +212 -0
- mqt/core/include/mqt-core/ir/operations/Control.hpp +142 -0
- mqt/core/include/mqt-core/ir/operations/Expression.hpp +847 -0
- mqt/core/include/mqt-core/ir/operations/IfElseOperation.hpp +169 -0
- mqt/core/include/mqt-core/ir/operations/NonUnitaryOperation.hpp +118 -0
- mqt/core/include/mqt-core/ir/operations/OpType.hpp +120 -0
- mqt/core/include/mqt-core/ir/operations/OpType.inc +76 -0
- mqt/core/include/mqt-core/ir/operations/Operation.hpp +247 -0
- mqt/core/include/mqt-core/ir/operations/StandardOperation.hpp +140 -0
- mqt/core/include/mqt-core/ir/operations/SymbolicOperation.hpp +144 -0
- mqt/core/include/mqt-core/mqt_na_qdmi/device.h +602 -0
- mqt/core/include/mqt-core/mqt_na_qdmi/types.h +78 -0
- mqt/core/include/mqt-core/na/NAComputation.hpp +185 -0
- mqt/core/include/mqt-core/na/device/Device.hpp +410 -0
- mqt/core/include/mqt-core/na/device/DeviceMemberInitializers.hpp +724 -0
- mqt/core/include/mqt-core/na/device/Generator.hpp +447 -0
- mqt/core/include/mqt-core/na/entities/Atom.hpp +62 -0
- mqt/core/include/mqt-core/na/entities/Location.hpp +154 -0
- mqt/core/include/mqt-core/na/entities/Zone.hpp +95 -0
- mqt/core/include/mqt-core/na/fomac/Device.hpp +169 -0
- mqt/core/include/mqt-core/na/mqt_core_na_export.h +43 -0
- mqt/core/include/mqt-core/na/operations/GlobalCZOp.hpp +38 -0
- mqt/core/include/mqt-core/na/operations/GlobalOp.hpp +58 -0
- mqt/core/include/mqt-core/na/operations/GlobalRYOp.hpp +42 -0
- mqt/core/include/mqt-core/na/operations/LoadOp.hpp +89 -0
- mqt/core/include/mqt-core/na/operations/LocalOp.hpp +56 -0
- mqt/core/include/mqt-core/na/operations/LocalRZOp.hpp +42 -0
- mqt/core/include/mqt-core/na/operations/LocalUOp.hpp +49 -0
- mqt/core/include/mqt-core/na/operations/MoveOp.hpp +66 -0
- mqt/core/include/mqt-core/na/operations/Op.hpp +62 -0
- mqt/core/include/mqt-core/na/operations/ShuttlingOp.hpp +51 -0
- mqt/core/include/mqt-core/na/operations/StoreOp.hpp +87 -0
- mqt/core/include/mqt-core/qasm3/Exception.hpp +85 -0
- mqt/core/include/mqt-core/qasm3/Gate.hpp +65 -0
- mqt/core/include/mqt-core/qasm3/Importer.hpp +192 -0
- mqt/core/include/mqt-core/qasm3/InstVisitor.hpp +145 -0
- mqt/core/include/mqt-core/qasm3/NestedEnvironment.hpp +41 -0
- mqt/core/include/mqt-core/qasm3/Parser.hpp +170 -0
- mqt/core/include/mqt-core/qasm3/Scanner.hpp +73 -0
- mqt/core/include/mqt-core/qasm3/Statement.hpp +486 -0
- mqt/core/include/mqt-core/qasm3/Statement_fwd.hpp +39 -0
- mqt/core/include/mqt-core/qasm3/StdGates.hpp +232 -0
- mqt/core/include/mqt-core/qasm3/Token.hpp +198 -0
- mqt/core/include/mqt-core/qasm3/Types.hpp +238 -0
- mqt/core/include/mqt-core/qasm3/Types_fwd.hpp +22 -0
- mqt/core/include/mqt-core/qasm3/mqt_core_qasm_export.h +43 -0
- mqt/core/include/mqt-core/qasm3/passes/CompilerPass.hpp +22 -0
- mqt/core/include/mqt-core/qasm3/passes/ConstEvalPass.hpp +102 -0
- mqt/core/include/mqt-core/qasm3/passes/TypeCheckPass.hpp +124 -0
- mqt/core/include/mqt-core/qdmi/Driver.hpp +431 -0
- mqt/core/include/mqt-core/zx/FunctionalityConstruction.hpp +125 -0
- mqt/core/include/mqt-core/zx/Rational.hpp +318 -0
- mqt/core/include/mqt-core/zx/Rules.hpp +132 -0
- mqt/core/include/mqt-core/zx/Simplify.hpp +182 -0
- mqt/core/include/mqt-core/zx/Utils.hpp +212 -0
- mqt/core/include/mqt-core/zx/ZXDefinitions.hpp +93 -0
- mqt/core/include/mqt-core/zx/ZXDiagram.hpp +480 -0
- mqt/core/include/mqt-core/zx/mqt_core_zx_export.h +43 -0
- mqt/core/include/nlohmann/adl_serializer.hpp +55 -0
- mqt/core/include/nlohmann/byte_container_with_subtype.hpp +103 -0
- mqt/core/include/nlohmann/detail/abi_macros.hpp +111 -0
- mqt/core/include/nlohmann/detail/conversions/from_json.hpp +577 -0
- mqt/core/include/nlohmann/detail/conversions/to_chars.hpp +1118 -0
- mqt/core/include/nlohmann/detail/conversions/to_json.hpp +479 -0
- mqt/core/include/nlohmann/detail/exceptions.hpp +291 -0
- mqt/core/include/nlohmann/detail/hash.hpp +129 -0
- mqt/core/include/nlohmann/detail/input/binary_reader.hpp +3068 -0
- mqt/core/include/nlohmann/detail/input/input_adapters.hpp +549 -0
- mqt/core/include/nlohmann/detail/input/json_sax.hpp +986 -0
- mqt/core/include/nlohmann/detail/input/lexer.hpp +1643 -0
- mqt/core/include/nlohmann/detail/input/parser.hpp +519 -0
- mqt/core/include/nlohmann/detail/input/position_t.hpp +37 -0
- mqt/core/include/nlohmann/detail/iterators/internal_iterator.hpp +35 -0
- mqt/core/include/nlohmann/detail/iterators/iter_impl.hpp +760 -0
- mqt/core/include/nlohmann/detail/iterators/iteration_proxy.hpp +235 -0
- mqt/core/include/nlohmann/detail/iterators/iterator_traits.hpp +61 -0
- mqt/core/include/nlohmann/detail/iterators/json_reverse_iterator.hpp +130 -0
- mqt/core/include/nlohmann/detail/iterators/primitive_iterator.hpp +132 -0
- mqt/core/include/nlohmann/detail/json_custom_base_class.hpp +39 -0
- mqt/core/include/nlohmann/detail/json_pointer.hpp +988 -0
- mqt/core/include/nlohmann/detail/json_ref.hpp +78 -0
- mqt/core/include/nlohmann/detail/macro_scope.hpp +595 -0
- mqt/core/include/nlohmann/detail/macro_unscope.hpp +46 -0
- mqt/core/include/nlohmann/detail/meta/call_std/begin.hpp +17 -0
- mqt/core/include/nlohmann/detail/meta/call_std/end.hpp +17 -0
- mqt/core/include/nlohmann/detail/meta/cpp_future.hpp +171 -0
- mqt/core/include/nlohmann/detail/meta/detected.hpp +70 -0
- mqt/core/include/nlohmann/detail/meta/identity_tag.hpp +21 -0
- mqt/core/include/nlohmann/detail/meta/is_sax.hpp +159 -0
- mqt/core/include/nlohmann/detail/meta/std_fs.hpp +29 -0
- mqt/core/include/nlohmann/detail/meta/type_traits.hpp +795 -0
- mqt/core/include/nlohmann/detail/meta/void_t.hpp +24 -0
- mqt/core/include/nlohmann/detail/output/binary_writer.hpp +1850 -0
- mqt/core/include/nlohmann/detail/output/output_adapters.hpp +147 -0
- mqt/core/include/nlohmann/detail/output/serializer.hpp +988 -0
- mqt/core/include/nlohmann/detail/string_concat.hpp +146 -0
- mqt/core/include/nlohmann/detail/string_escape.hpp +72 -0
- mqt/core/include/nlohmann/detail/string_utils.hpp +37 -0
- mqt/core/include/nlohmann/detail/value_t.hpp +118 -0
- mqt/core/include/nlohmann/json.hpp +5306 -0
- mqt/core/include/nlohmann/json_fwd.hpp +75 -0
- mqt/core/include/nlohmann/ordered_map.hpp +359 -0
- mqt/core/include/nlohmann/thirdparty/hedley/hedley.hpp +2045 -0
- mqt/core/include/nlohmann/thirdparty/hedley/hedley_undef.hpp +158 -0
- mqt/core/include/qdmi/qdmi/client.h +990 -0
- mqt/core/include/qdmi/qdmi/constants.h +1139 -0
- mqt/core/include/qdmi/qdmi/device.h +602 -0
- mqt/core/include/qdmi/qdmi/types.h +78 -0
- mqt/core/include/spdlog/async.h +99 -0
- mqt/core/include/spdlog/async_logger-inl.h +84 -0
- mqt/core/include/spdlog/async_logger.h +74 -0
- mqt/core/include/spdlog/cfg/argv.h +40 -0
- mqt/core/include/spdlog/cfg/env.h +36 -0
- mqt/core/include/spdlog/cfg/helpers-inl.h +107 -0
- mqt/core/include/spdlog/cfg/helpers.h +29 -0
- mqt/core/include/spdlog/common-inl.h +68 -0
- mqt/core/include/spdlog/common.h +406 -0
- mqt/core/include/spdlog/details/backtracer-inl.h +63 -0
- mqt/core/include/spdlog/details/backtracer.h +45 -0
- mqt/core/include/spdlog/details/circular_q.h +115 -0
- mqt/core/include/spdlog/details/console_globals.h +28 -0
- mqt/core/include/spdlog/details/file_helper-inl.h +153 -0
- mqt/core/include/spdlog/details/file_helper.h +61 -0
- mqt/core/include/spdlog/details/fmt_helper.h +141 -0
- mqt/core/include/spdlog/details/log_msg-inl.h +44 -0
- mqt/core/include/spdlog/details/log_msg.h +40 -0
- mqt/core/include/spdlog/details/log_msg_buffer-inl.h +54 -0
- mqt/core/include/spdlog/details/log_msg_buffer.h +32 -0
- mqt/core/include/spdlog/details/mpmc_blocking_q.h +177 -0
- mqt/core/include/spdlog/details/null_mutex.h +35 -0
- mqt/core/include/spdlog/details/os-inl.h +606 -0
- mqt/core/include/spdlog/details/os.h +127 -0
- mqt/core/include/spdlog/details/periodic_worker-inl.h +26 -0
- mqt/core/include/spdlog/details/periodic_worker.h +58 -0
- mqt/core/include/spdlog/details/registry-inl.h +270 -0
- mqt/core/include/spdlog/details/registry.h +131 -0
- mqt/core/include/spdlog/details/synchronous_factory.h +22 -0
- mqt/core/include/spdlog/details/tcp_client-windows.h +135 -0
- mqt/core/include/spdlog/details/tcp_client.h +127 -0
- mqt/core/include/spdlog/details/thread_pool-inl.h +126 -0
- mqt/core/include/spdlog/details/thread_pool.h +117 -0
- mqt/core/include/spdlog/details/udp_client-windows.h +98 -0
- mqt/core/include/spdlog/details/udp_client.h +81 -0
- mqt/core/include/spdlog/details/windows_include.h +11 -0
- mqt/core/include/spdlog/fmt/bin_to_hex.h +224 -0
- mqt/core/include/spdlog/fmt/bundled/args.h +220 -0
- mqt/core/include/spdlog/fmt/bundled/base.h +2989 -0
- mqt/core/include/spdlog/fmt/bundled/chrono.h +2330 -0
- mqt/core/include/spdlog/fmt/bundled/color.h +637 -0
- mqt/core/include/spdlog/fmt/bundled/compile.h +539 -0
- mqt/core/include/spdlog/fmt/bundled/core.h +5 -0
- mqt/core/include/spdlog/fmt/bundled/fmt.license.rst +27 -0
- mqt/core/include/spdlog/fmt/bundled/format-inl.h +1948 -0
- mqt/core/include/spdlog/fmt/bundled/format.h +4244 -0
- mqt/core/include/spdlog/fmt/bundled/os.h +427 -0
- mqt/core/include/spdlog/fmt/bundled/ostream.h +167 -0
- mqt/core/include/spdlog/fmt/bundled/printf.h +633 -0
- mqt/core/include/spdlog/fmt/bundled/ranges.h +850 -0
- mqt/core/include/spdlog/fmt/bundled/std.h +728 -0
- mqt/core/include/spdlog/fmt/bundled/xchar.h +369 -0
- mqt/core/include/spdlog/fmt/chrono.h +23 -0
- mqt/core/include/spdlog/fmt/compile.h +23 -0
- mqt/core/include/spdlog/fmt/fmt.h +30 -0
- mqt/core/include/spdlog/fmt/ostr.h +23 -0
- mqt/core/include/spdlog/fmt/ranges.h +23 -0
- mqt/core/include/spdlog/fmt/std.h +24 -0
- mqt/core/include/spdlog/fmt/xchar.h +23 -0
- mqt/core/include/spdlog/formatter.h +17 -0
- mqt/core/include/spdlog/fwd.h +18 -0
- mqt/core/include/spdlog/logger-inl.h +198 -0
- mqt/core/include/spdlog/logger.h +379 -0
- mqt/core/include/spdlog/mdc.h +52 -0
- mqt/core/include/spdlog/pattern_formatter-inl.h +1340 -0
- mqt/core/include/spdlog/pattern_formatter.h +118 -0
- mqt/core/include/spdlog/sinks/android_sink.h +137 -0
- mqt/core/include/spdlog/sinks/ansicolor_sink-inl.h +142 -0
- mqt/core/include/spdlog/sinks/ansicolor_sink.h +116 -0
- mqt/core/include/spdlog/sinks/base_sink-inl.h +59 -0
- mqt/core/include/spdlog/sinks/base_sink.h +51 -0
- mqt/core/include/spdlog/sinks/basic_file_sink-inl.h +48 -0
- mqt/core/include/spdlog/sinks/basic_file_sink.h +66 -0
- mqt/core/include/spdlog/sinks/callback_sink.h +56 -0
- mqt/core/include/spdlog/sinks/daily_file_sink.h +254 -0
- mqt/core/include/spdlog/sinks/dist_sink.h +81 -0
- mqt/core/include/spdlog/sinks/dup_filter_sink.h +91 -0
- mqt/core/include/spdlog/sinks/hourly_file_sink.h +193 -0
- mqt/core/include/spdlog/sinks/kafka_sink.h +119 -0
- mqt/core/include/spdlog/sinks/mongo_sink.h +108 -0
- mqt/core/include/spdlog/sinks/msvc_sink.h +68 -0
- mqt/core/include/spdlog/sinks/null_sink.h +41 -0
- mqt/core/include/spdlog/sinks/ostream_sink.h +43 -0
- mqt/core/include/spdlog/sinks/qt_sinks.h +304 -0
- mqt/core/include/spdlog/sinks/ringbuffer_sink.h +67 -0
- mqt/core/include/spdlog/sinks/rotating_file_sink-inl.h +179 -0
- mqt/core/include/spdlog/sinks/rotating_file_sink.h +93 -0
- mqt/core/include/spdlog/sinks/sink-inl.h +22 -0
- mqt/core/include/spdlog/sinks/sink.h +34 -0
- mqt/core/include/spdlog/sinks/stdout_color_sinks-inl.h +38 -0
- mqt/core/include/spdlog/sinks/stdout_color_sinks.h +49 -0
- mqt/core/include/spdlog/sinks/stdout_sinks-inl.h +127 -0
- mqt/core/include/spdlog/sinks/stdout_sinks.h +84 -0
- mqt/core/include/spdlog/sinks/syslog_sink.h +104 -0
- mqt/core/include/spdlog/sinks/systemd_sink.h +121 -0
- mqt/core/include/spdlog/sinks/tcp_sink.h +75 -0
- mqt/core/include/spdlog/sinks/udp_sink.h +69 -0
- mqt/core/include/spdlog/sinks/win_eventlog_sink.h +260 -0
- mqt/core/include/spdlog/sinks/wincolor_sink-inl.h +172 -0
- mqt/core/include/spdlog/sinks/wincolor_sink.h +82 -0
- mqt/core/include/spdlog/spdlog-inl.h +96 -0
- mqt/core/include/spdlog/spdlog.h +357 -0
- mqt/core/include/spdlog/stopwatch.h +66 -0
- mqt/core/include/spdlog/tweakme.h +148 -0
- mqt/core/include/spdlog/version.h +11 -0
- mqt/core/ir/__init__.pyi +2078 -0
- mqt/core/ir/operations.pyi +1011 -0
- mqt/core/ir/registers.pyi +91 -0
- mqt/core/ir/symbolic.pyi +177 -0
- mqt/core/ir.cp314t-win_amd64.pyd +0 -0
- mqt/core/lib/mqt-core-algorithms.lib +0 -0
- mqt/core/lib/mqt-core-circuit-optimizer.lib +0 -0
- mqt/core/lib/mqt-core-dd.lib +0 -0
- mqt/core/lib/mqt-core-ds.lib +0 -0
- mqt/core/lib/mqt-core-fomac.lib +0 -0
- mqt/core/lib/mqt-core-ir.lib +0 -0
- mqt/core/lib/mqt-core-na-fomac.lib +0 -0
- mqt/core/lib/mqt-core-na.lib +0 -0
- mqt/core/lib/mqt-core-qasm.lib +0 -0
- mqt/core/lib/mqt-core-qdmi-driver.lib +0 -0
- mqt/core/lib/mqt-core-qdmi-na-device-gen.lib +0 -0
- mqt/core/lib/mqt-core-qdmi-na-device.lib +0 -0
- mqt/core/lib/mqt-core-zx.lib +0 -0
- mqt/core/lib/pkgconfig/spdlog.pc +13 -0
- mqt/core/lib/spdlog.lib +0 -0
- mqt/core/na/__init__.py +12 -0
- mqt/core/na/fomac.cp314t-win_amd64.pyd +0 -0
- mqt/core/na/fomac.pyi +117 -0
- mqt/core/nlohmann_json.natvis +278 -0
- mqt/core/plugins/__init__.py +9 -0
- mqt/core/plugins/qiskit/__init__.py +19 -0
- mqt/core/plugins/qiskit/mqt_to_qiskit.py +420 -0
- mqt/core/plugins/qiskit/qiskit_to_mqt.py +562 -0
- mqt/core/py.typed +2 -0
- mqt/core/share/cmake/mqt-core/AddMQTPythonBinding.cmake +55 -0
- mqt/core/share/cmake/mqt-core/Cache.cmake +33 -0
- mqt/core/share/cmake/mqt-core/FindGMP.cmake +103 -0
- mqt/core/share/cmake/mqt-core/PackageAddTest.cmake +46 -0
- mqt/core/share/cmake/mqt-core/PreventInSourceBuilds.cmake +25 -0
- mqt/core/share/cmake/mqt-core/StandardProjectSettings.cmake +87 -0
- mqt/core/share/cmake/mqt-core/mqt-core-config-version.cmake +85 -0
- mqt/core/share/cmake/mqt-core/mqt-core-config.cmake +52 -0
- mqt/core/share/cmake/mqt-core/mqt-core-targets-release.cmake +141 -0
- mqt/core/share/cmake/mqt-core/mqt-core-targets.cmake +445 -0
- mqt/core/share/cmake/nlohmann_json/nlohmann_jsonConfig.cmake +15 -0
- mqt/core/share/cmake/nlohmann_json/nlohmann_jsonConfigVersion.cmake +20 -0
- mqt/core/share/cmake/nlohmann_json/nlohmann_jsonTargets.cmake +110 -0
- mqt/core/share/cmake/qdmi/Cache.cmake +44 -0
- mqt/core/share/cmake/qdmi/PrefixHandling.cmake +78 -0
- mqt/core/share/cmake/qdmi/prefix_defs.txt +26 -0
- mqt/core/share/cmake/qdmi/qdmi-config-version.cmake +85 -0
- mqt/core/share/cmake/qdmi/qdmi-config.cmake +42 -0
- mqt/core/share/cmake/qdmi/qdmi-targets.cmake +129 -0
- mqt/core/share/cmake/spdlog/spdlogConfig.cmake +44 -0
- mqt/core/share/cmake/spdlog/spdlogConfigTargets-release.cmake +19 -0
- mqt/core/share/cmake/spdlog/spdlogConfigTargets.cmake +121 -0
- mqt/core/share/cmake/spdlog/spdlogConfigVersion.cmake +65 -0
- mqt/core/share/pkgconfig/nlohmann_json.pc +7 -0
- mqt_core-3.3.2.dist-info/DELVEWHEEL +2 -0
- mqt_core-3.3.2.dist-info/METADATA +210 -0
- mqt_core-3.3.2.dist-info/RECORD +537 -0
- mqt_core-3.3.2.dist-info/WHEEL +5 -0
- mqt_core-3.3.2.dist-info/entry_points.txt +4 -0
- mqt_core-3.3.2.dist-info/licenses/LICENSE.md +22 -0
- mqt_core.libs/msvcp140.dll +0 -0
|
@@ -0,0 +1,4060 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright 2011 John Maddock.
|
|
3
|
+
// Copyright 2021 Matt Borland. Distributed under the Boost
|
|
4
|
+
// Software License, Version 1.0. (See accompanying file
|
|
5
|
+
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
6
|
+
|
|
7
|
+
#ifndef BOOST_MP_GMP_HPP
|
|
8
|
+
#define BOOST_MP_GMP_HPP
|
|
9
|
+
|
|
10
|
+
#include <boost/multiprecision/detail/standalone_config.hpp>
|
|
11
|
+
#include <boost/multiprecision/number.hpp>
|
|
12
|
+
#include <boost/multiprecision/debug_adaptor.hpp>
|
|
13
|
+
#include <boost/multiprecision/detail/integer_ops.hpp>
|
|
14
|
+
#include <boost/multiprecision/detail/float128_functions.hpp>
|
|
15
|
+
#include <boost/multiprecision/detail/digits.hpp>
|
|
16
|
+
#include <boost/multiprecision/detail/atomic.hpp>
|
|
17
|
+
#include <boost/multiprecision/detail/hash.hpp>
|
|
18
|
+
#include <boost/multiprecision/detail/no_exceptions_support.hpp>
|
|
19
|
+
#include <boost/multiprecision/detail/assert.hpp>
|
|
20
|
+
#include <boost/multiprecision/detail/fpclassify.hpp>
|
|
21
|
+
#include <boost/multiprecision/detail/string_helpers.hpp>
|
|
22
|
+
#include <algorithm>
|
|
23
|
+
#include <cctype>
|
|
24
|
+
#include <cfloat>
|
|
25
|
+
#include <climits>
|
|
26
|
+
#include <clocale>
|
|
27
|
+
#include <cmath>
|
|
28
|
+
#include <cstdint>
|
|
29
|
+
#include <cstdlib>
|
|
30
|
+
#include <cstring>
|
|
31
|
+
#include <iomanip>
|
|
32
|
+
#include <iostream>
|
|
33
|
+
#include <limits>
|
|
34
|
+
#include <memory>
|
|
35
|
+
#include <type_traits>
|
|
36
|
+
#include <utility>
|
|
37
|
+
|
|
38
|
+
//
|
|
39
|
+
// Some includes we need from Boost.Math, since we rely on that library to provide these functions:
|
|
40
|
+
//
|
|
41
|
+
#ifdef BOOST_MP_MATH_AVAILABLE
|
|
42
|
+
#include <boost/math/special_functions/asinh.hpp>
|
|
43
|
+
#include <boost/math/special_functions/acosh.hpp>
|
|
44
|
+
#include <boost/math/special_functions/atanh.hpp>
|
|
45
|
+
#include <boost/math/special_functions/cbrt.hpp>
|
|
46
|
+
#include <boost/math/special_functions/expm1.hpp>
|
|
47
|
+
#include <boost/math/special_functions/gamma.hpp>
|
|
48
|
+
#endif
|
|
49
|
+
|
|
50
|
+
#ifdef BOOST_MSVC
|
|
51
|
+
#pragma warning(push)
|
|
52
|
+
#pragma warning(disable : 4127)
|
|
53
|
+
#endif
|
|
54
|
+
#include <gmp.h>
|
|
55
|
+
#ifdef BOOST_MSVC
|
|
56
|
+
#pragma warning(pop)
|
|
57
|
+
#endif
|
|
58
|
+
|
|
59
|
+
#if defined(__MPIR_VERSION) && defined(__MPIR_VERSION_MINOR) && defined(__MPIR_VERSION_PATCHLEVEL)
|
|
60
|
+
#define BOOST_MP_MPIR_VERSION (__MPIR_VERSION * 10000 + __MPIR_VERSION_MINOR * 100 + __MPIR_VERSION_PATCHLEVEL)
|
|
61
|
+
#else
|
|
62
|
+
#define BOOST_MP_MPIR_VERSION 0
|
|
63
|
+
#endif
|
|
64
|
+
|
|
65
|
+
namespace boost {
|
|
66
|
+
namespace multiprecision {
|
|
67
|
+
namespace backends {
|
|
68
|
+
|
|
69
|
+
#ifdef BOOST_MSVC
|
|
70
|
+
// warning C4127: conditional expression is constant
|
|
71
|
+
#pragma warning(push)
|
|
72
|
+
//#pragma warning(disable : 4127)
|
|
73
|
+
#endif
|
|
74
|
+
|
|
75
|
+
template <unsigned digits10>
|
|
76
|
+
struct gmp_float;
|
|
77
|
+
struct gmp_int;
|
|
78
|
+
struct gmp_rational;
|
|
79
|
+
|
|
80
|
+
} // namespace backends
|
|
81
|
+
|
|
82
|
+
template <>
|
|
83
|
+
struct number_category<backends::gmp_int> : public std::integral_constant<int, number_kind_integer>
|
|
84
|
+
{};
|
|
85
|
+
template <>
|
|
86
|
+
struct number_category<backends::gmp_rational> : public std::integral_constant<int, number_kind_rational>
|
|
87
|
+
{};
|
|
88
|
+
template <unsigned digits10>
|
|
89
|
+
struct number_category<backends::gmp_float<digits10> > : public std::integral_constant<int, number_kind_floating_point>
|
|
90
|
+
{};
|
|
91
|
+
|
|
92
|
+
namespace backends {
|
|
93
|
+
//
|
|
94
|
+
// Within this file, the only functions we mark as noexcept are those that manipulate
|
|
95
|
+
// (but don't create) an mpf_t. All other types may allocate at pretty much any time
|
|
96
|
+
// via a user-supplied allocator, and therefore throw.
|
|
97
|
+
//
|
|
98
|
+
namespace detail {
|
|
99
|
+
|
|
100
|
+
template <unsigned digits10>
|
|
101
|
+
struct gmp_float_imp
|
|
102
|
+
{
|
|
103
|
+
#ifdef BOOST_HAS_LONG_LONG
|
|
104
|
+
using signed_types = std::tuple<long, long long> ;
|
|
105
|
+
using unsigned_types = std::tuple<unsigned long, unsigned long long>;
|
|
106
|
+
#else
|
|
107
|
+
using signed_types = std::tuple<long> ;
|
|
108
|
+
using unsigned_types = std::tuple<unsigned long>;
|
|
109
|
+
#endif
|
|
110
|
+
using float_types = std::tuple<double, long double>;
|
|
111
|
+
using exponent_type = long ;
|
|
112
|
+
|
|
113
|
+
gmp_float_imp() noexcept
|
|
114
|
+
{
|
|
115
|
+
m_data[0]._mp_d = nullptr; // uninitialized m_data
|
|
116
|
+
m_data[0]._mp_prec = 1;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
gmp_float_imp(const gmp_float_imp& o)
|
|
120
|
+
{
|
|
121
|
+
//
|
|
122
|
+
// We have to do an init followed by a set here, otherwise *this may be at
|
|
123
|
+
// a lower precision than o: seems like mpf_init_set copies just enough bits
|
|
124
|
+
// to get the right value, but if it's then used in further calculations
|
|
125
|
+
// things go badly wrong!!
|
|
126
|
+
//
|
|
127
|
+
mpf_init2(m_data, preserve_source_precision() ? mpf_get_prec(o.data()) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
|
|
128
|
+
if (o.m_data[0]._mp_d)
|
|
129
|
+
mpf_set(m_data, o.m_data);
|
|
130
|
+
}
|
|
131
|
+
// rvalue copy
|
|
132
|
+
gmp_float_imp(gmp_float_imp&& o) noexcept
|
|
133
|
+
{
|
|
134
|
+
if ((this->get_default_options() == variable_precision_options::preserve_target_precision) && (mpf_get_prec(o.data()) != boost::multiprecision::detail::digits10_2_2(get_default_precision())))
|
|
135
|
+
{
|
|
136
|
+
mpf_init2(m_data, boost::multiprecision::detail::digits10_2_2(get_default_precision()));
|
|
137
|
+
*this = static_cast<const gmp_float_imp&>(o);
|
|
138
|
+
}
|
|
139
|
+
else
|
|
140
|
+
{
|
|
141
|
+
m_data[0] = o.m_data[0];
|
|
142
|
+
o.m_data[0]._mp_d = nullptr;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
gmp_float_imp& operator=(const gmp_float_imp& o)
|
|
147
|
+
{
|
|
148
|
+
if (m_data[0]._mp_d == nullptr)
|
|
149
|
+
{
|
|
150
|
+
mpf_init2(m_data, preserve_source_precision() ? mpf_get_prec(o.data()) : boost::multiprecision::detail::digits10_2_2(get_default_precision()));
|
|
151
|
+
mpf_set(m_data, o.m_data);
|
|
152
|
+
}
|
|
153
|
+
else if (preserve_source_precision() && (mpf_get_prec(data()) != mpf_get_prec(o.data())))
|
|
154
|
+
{
|
|
155
|
+
mpf_t t;
|
|
156
|
+
mpf_init2(t, mpf_get_prec(o.data()));
|
|
157
|
+
mpf_set(t, o.data());
|
|
158
|
+
mpf_swap(data(), t);
|
|
159
|
+
mpf_clear(t);
|
|
160
|
+
}
|
|
161
|
+
else
|
|
162
|
+
{
|
|
163
|
+
mpf_set(m_data, o.m_data);
|
|
164
|
+
}
|
|
165
|
+
return *this;
|
|
166
|
+
}
|
|
167
|
+
// rvalue assign
|
|
168
|
+
gmp_float_imp& operator=(gmp_float_imp&& o) noexcept
|
|
169
|
+
{
|
|
170
|
+
if ((this->get_default_options() == variable_precision_options::preserve_target_precision) && (mpf_get_prec(o.data()) != mpf_get_prec(data())))
|
|
171
|
+
*this = static_cast<const gmp_float_imp&>(o);
|
|
172
|
+
else
|
|
173
|
+
{
|
|
174
|
+
mpf_swap(m_data, o.m_data);
|
|
175
|
+
}
|
|
176
|
+
return *this;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
#ifdef BOOST_HAS_LONG_LONG
|
|
180
|
+
#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
|
|
181
|
+
gmp_float_imp& operator=(unsigned long long i)
|
|
182
|
+
{
|
|
183
|
+
*this = static_cast<unsigned long>(i);
|
|
184
|
+
return *this;
|
|
185
|
+
}
|
|
186
|
+
#else
|
|
187
|
+
gmp_float_imp& operator=(unsigned long long i)
|
|
188
|
+
{
|
|
189
|
+
if (m_data[0]._mp_d == nullptr)
|
|
190
|
+
{
|
|
191
|
+
mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
|
|
192
|
+
}
|
|
193
|
+
unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
|
|
194
|
+
unsigned shift = 0;
|
|
195
|
+
mpf_t t;
|
|
196
|
+
mpf_init2(t, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
|
|
197
|
+
mpf_set_ui(m_data, 0);
|
|
198
|
+
while (i)
|
|
199
|
+
{
|
|
200
|
+
mpf_set_ui(t, static_cast<unsigned long>(i & mask));
|
|
201
|
+
if (shift)
|
|
202
|
+
mpf_mul_2exp(t, t, shift);
|
|
203
|
+
mpf_add(m_data, m_data, t);
|
|
204
|
+
shift += std::numeric_limits<unsigned long>::digits;
|
|
205
|
+
i >>= std::numeric_limits<unsigned long>::digits;
|
|
206
|
+
}
|
|
207
|
+
mpf_clear(t);
|
|
208
|
+
return *this;
|
|
209
|
+
}
|
|
210
|
+
#endif
|
|
211
|
+
gmp_float_imp& operator=(long long i)
|
|
212
|
+
{
|
|
213
|
+
if (m_data[0]._mp_d == nullptr)
|
|
214
|
+
{
|
|
215
|
+
mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
|
|
216
|
+
}
|
|
217
|
+
bool neg = i < 0;
|
|
218
|
+
*this = static_cast<unsigned long long>(boost::multiprecision::detail::unsigned_abs(i));
|
|
219
|
+
if (neg)
|
|
220
|
+
mpf_neg(m_data, m_data);
|
|
221
|
+
return *this;
|
|
222
|
+
}
|
|
223
|
+
#endif
|
|
224
|
+
gmp_float_imp& operator=(unsigned long i)
|
|
225
|
+
{
|
|
226
|
+
if (m_data[0]._mp_d == nullptr)
|
|
227
|
+
{
|
|
228
|
+
mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
|
|
229
|
+
}
|
|
230
|
+
mpf_set_ui(m_data, i);
|
|
231
|
+
return *this;
|
|
232
|
+
}
|
|
233
|
+
gmp_float_imp& operator=(long i)
|
|
234
|
+
{
|
|
235
|
+
if (m_data[0]._mp_d == nullptr)
|
|
236
|
+
{
|
|
237
|
+
mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
|
|
238
|
+
}
|
|
239
|
+
mpf_set_si(m_data, i);
|
|
240
|
+
return *this;
|
|
241
|
+
}
|
|
242
|
+
#ifdef BOOST_HAS_INT128
|
|
243
|
+
gmp_float_imp& operator=(uint128_type i)
|
|
244
|
+
{
|
|
245
|
+
if (m_data[0]._mp_d == nullptr)
|
|
246
|
+
{
|
|
247
|
+
mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
|
|
248
|
+
}
|
|
249
|
+
unsigned long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
|
|
250
|
+
unsigned shift = 0;
|
|
251
|
+
mpf_t t;
|
|
252
|
+
mpf_init2(t, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
|
|
253
|
+
mpf_set_ui(m_data, 0);
|
|
254
|
+
while (i)
|
|
255
|
+
{
|
|
256
|
+
mpf_set_ui(t, static_cast<unsigned long>(i & mask));
|
|
257
|
+
if (shift)
|
|
258
|
+
mpf_mul_2exp(t, t, shift);
|
|
259
|
+
mpf_add(m_data, m_data, t);
|
|
260
|
+
shift += std::numeric_limits<unsigned long>::digits;
|
|
261
|
+
i >>= std::numeric_limits<unsigned long>::digits;
|
|
262
|
+
}
|
|
263
|
+
mpf_clear(t);
|
|
264
|
+
return *this;
|
|
265
|
+
}
|
|
266
|
+
gmp_float_imp& operator=(int128_type i)
|
|
267
|
+
{
|
|
268
|
+
if (m_data[0]._mp_d == nullptr)
|
|
269
|
+
{
|
|
270
|
+
mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
|
|
271
|
+
}
|
|
272
|
+
bool neg = i < 0;
|
|
273
|
+
*this = static_cast<uint128_type>(boost::multiprecision::detail::unsigned_abs(i));
|
|
274
|
+
if (neg)
|
|
275
|
+
mpf_neg(m_data, m_data);
|
|
276
|
+
return *this;
|
|
277
|
+
}
|
|
278
|
+
#endif
|
|
279
|
+
gmp_float_imp& operator=(double d)
|
|
280
|
+
{
|
|
281
|
+
if (m_data[0]._mp_d == nullptr)
|
|
282
|
+
{
|
|
283
|
+
mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
|
|
284
|
+
}
|
|
285
|
+
mpf_set_d(m_data, d);
|
|
286
|
+
return *this;
|
|
287
|
+
}
|
|
288
|
+
template <class F>
|
|
289
|
+
gmp_float_imp& assign_float(F a)
|
|
290
|
+
{
|
|
291
|
+
BOOST_MP_FLOAT128_USING using std::floor; using std::frexp; using std::ldexp;
|
|
292
|
+
|
|
293
|
+
if (m_data[0]._mp_d == nullptr)
|
|
294
|
+
{
|
|
295
|
+
mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (a == 0)
|
|
299
|
+
{
|
|
300
|
+
mpf_set_si(m_data, 0);
|
|
301
|
+
return *this;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (a == 1)
|
|
305
|
+
{
|
|
306
|
+
mpf_set_si(m_data, 1);
|
|
307
|
+
return *this;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
BOOST_MP_ASSERT(!BOOST_MP_ISINF(a));
|
|
311
|
+
BOOST_MP_ASSERT(!BOOST_MP_ISNAN(a));
|
|
312
|
+
|
|
313
|
+
int e;
|
|
314
|
+
F f, term;
|
|
315
|
+
mpf_set_ui(m_data, 0u);
|
|
316
|
+
|
|
317
|
+
f = frexp(a, &e);
|
|
318
|
+
|
|
319
|
+
constexpr int shift = std::numeric_limits<int>::digits - 1;
|
|
320
|
+
|
|
321
|
+
while (f)
|
|
322
|
+
{
|
|
323
|
+
// extract int sized bits from f:
|
|
324
|
+
f = ldexp(f, shift);
|
|
325
|
+
term = floor(f);
|
|
326
|
+
e -= shift;
|
|
327
|
+
mpf_mul_2exp(m_data, m_data, shift);
|
|
328
|
+
if (term > 0)
|
|
329
|
+
mpf_add_ui(m_data, m_data, static_cast<unsigned>(term));
|
|
330
|
+
else
|
|
331
|
+
mpf_sub_ui(m_data, m_data, static_cast<unsigned>(-term));
|
|
332
|
+
f -= term;
|
|
333
|
+
}
|
|
334
|
+
if (e > 0)
|
|
335
|
+
mpf_mul_2exp(m_data, m_data, e);
|
|
336
|
+
else if (e < 0)
|
|
337
|
+
mpf_div_2exp(m_data, m_data, -e);
|
|
338
|
+
return *this;
|
|
339
|
+
}
|
|
340
|
+
gmp_float_imp& operator=(long double a)
|
|
341
|
+
{
|
|
342
|
+
return assign_float(a);
|
|
343
|
+
}
|
|
344
|
+
#ifdef BOOST_HAS_FLOAT128
|
|
345
|
+
gmp_float_imp& operator= (float128_type a)
|
|
346
|
+
{
|
|
347
|
+
return assign_float(a);
|
|
348
|
+
}
|
|
349
|
+
#endif
|
|
350
|
+
gmp_float_imp& operator=(const char* s)
|
|
351
|
+
{
|
|
352
|
+
if (m_data[0]._mp_d == nullptr)
|
|
353
|
+
{
|
|
354
|
+
mpf_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
|
|
355
|
+
}
|
|
356
|
+
if (s && (*s == '+'))
|
|
357
|
+
++s; // Leading "+" sign not supported by mpf_set_str:
|
|
358
|
+
//
|
|
359
|
+
// Validate the string as mpf_set_str does a poor job of this:
|
|
360
|
+
//
|
|
361
|
+
static const char* digits = "0123456789";
|
|
362
|
+
const char* p = s;
|
|
363
|
+
if (*s == '-')
|
|
364
|
+
++s;
|
|
365
|
+
s += boost::multiprecision::detail::find_first_not_of(s, s + std::strlen(s), digits);
|
|
366
|
+
std::lconv const* l = std::localeconv();
|
|
367
|
+
std::size_t len = strlen(l->decimal_point);
|
|
368
|
+
if (std::find(l->decimal_point, l->decimal_point + len, *s) != l->decimal_point + len)
|
|
369
|
+
{
|
|
370
|
+
++s;
|
|
371
|
+
s += boost::multiprecision::detail::find_first_not_of(s, s + std::strlen(s), digits);
|
|
372
|
+
}
|
|
373
|
+
if ((*s == 'e') || (*s == 'E'))
|
|
374
|
+
{
|
|
375
|
+
++s;
|
|
376
|
+
if ((*s == '+') || (*s == '-'))
|
|
377
|
+
++s;
|
|
378
|
+
s += boost::multiprecision::detail::find_first_not_of(s, s + std::strlen(s), digits);
|
|
379
|
+
}
|
|
380
|
+
if(*s)
|
|
381
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid floating point number.")));
|
|
382
|
+
|
|
383
|
+
s = p;
|
|
384
|
+
|
|
385
|
+
if (0 != mpf_set_str(m_data, s, 10))
|
|
386
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid floating point number.")));
|
|
387
|
+
return *this;
|
|
388
|
+
}
|
|
389
|
+
void swap(gmp_float_imp& o) noexcept
|
|
390
|
+
{
|
|
391
|
+
mpf_swap(m_data, o.m_data);
|
|
392
|
+
}
|
|
393
|
+
std::string str(std::streamsize digits, std::ios_base::fmtflags f) const
|
|
394
|
+
{
|
|
395
|
+
BOOST_MP_ASSERT(m_data[0]._mp_d);
|
|
396
|
+
|
|
397
|
+
bool scientific = (f & std::ios_base::scientific) == std::ios_base::scientific;
|
|
398
|
+
bool fixed = (f & std::ios_base::fixed) == std::ios_base::fixed;
|
|
399
|
+
std::streamsize org_digits(digits);
|
|
400
|
+
|
|
401
|
+
if (scientific && digits)
|
|
402
|
+
++digits;
|
|
403
|
+
|
|
404
|
+
std::string result;
|
|
405
|
+
mp_exp_t e;
|
|
406
|
+
void* (*alloc_func_ptr)(size_t);
|
|
407
|
+
void* (*realloc_func_ptr)(void*, size_t, size_t);
|
|
408
|
+
void (*free_func_ptr)(void*, size_t);
|
|
409
|
+
mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
|
|
410
|
+
|
|
411
|
+
if (mpf_sgn(m_data) == 0)
|
|
412
|
+
{
|
|
413
|
+
e = 0;
|
|
414
|
+
result = "0";
|
|
415
|
+
if (fixed && digits)
|
|
416
|
+
++digits;
|
|
417
|
+
}
|
|
418
|
+
else
|
|
419
|
+
{
|
|
420
|
+
char* ps = mpf_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data);
|
|
421
|
+
--e; // To match with what our formatter expects.
|
|
422
|
+
if (fixed)
|
|
423
|
+
{
|
|
424
|
+
// Oops we actually need a different number of digits to what we asked for:
|
|
425
|
+
(*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
|
|
426
|
+
digits += e + 1;
|
|
427
|
+
if (digits == 0)
|
|
428
|
+
{
|
|
429
|
+
// We need to get *all* the digits and then possibly round up,
|
|
430
|
+
// we end up with either "0" or "1" as the result.
|
|
431
|
+
ps = mpf_get_str(nullptr, &e, 10, 0, m_data);
|
|
432
|
+
--e;
|
|
433
|
+
unsigned offset = *ps == '-' ? 1 : 0;
|
|
434
|
+
if (ps[offset] > '5')
|
|
435
|
+
{
|
|
436
|
+
++e;
|
|
437
|
+
ps[offset] = '1';
|
|
438
|
+
ps[offset + 1] = 0;
|
|
439
|
+
}
|
|
440
|
+
else if (ps[offset] == '5')
|
|
441
|
+
{
|
|
442
|
+
unsigned i = offset + 1;
|
|
443
|
+
bool round_up = false;
|
|
444
|
+
while (ps[i] != 0)
|
|
445
|
+
{
|
|
446
|
+
if (ps[i] != '0')
|
|
447
|
+
{
|
|
448
|
+
round_up = true;
|
|
449
|
+
break;
|
|
450
|
+
}
|
|
451
|
+
++i;
|
|
452
|
+
}
|
|
453
|
+
if (round_up)
|
|
454
|
+
{
|
|
455
|
+
++e;
|
|
456
|
+
ps[offset] = '1';
|
|
457
|
+
ps[offset + 1] = 0;
|
|
458
|
+
}
|
|
459
|
+
else
|
|
460
|
+
{
|
|
461
|
+
ps[offset] = '0';
|
|
462
|
+
ps[offset + 1] = 0;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
else
|
|
466
|
+
{
|
|
467
|
+
ps[offset] = '0';
|
|
468
|
+
ps[offset + 1] = 0;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
else if (digits > 0)
|
|
472
|
+
{
|
|
473
|
+
mp_exp_t old_e = e;
|
|
474
|
+
ps = mpf_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data);
|
|
475
|
+
--e; // To match with what our formatter expects.
|
|
476
|
+
if (old_e > e)
|
|
477
|
+
{
|
|
478
|
+
// in some cases, when we ask for more digits of precision, it will
|
|
479
|
+
// change the number of digits to the left of the decimal, if that
|
|
480
|
+
// happens, account for it here.
|
|
481
|
+
// example: cout << fixed << setprecision(3) << mpf_float_50("99.9809")
|
|
482
|
+
digits -= old_e - e;
|
|
483
|
+
(*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
|
|
484
|
+
ps = mpf_get_str(nullptr, &e, 10, static_cast<std::size_t>(digits), m_data);
|
|
485
|
+
--e; // To match with what our formatter expects.
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
else
|
|
489
|
+
{
|
|
490
|
+
ps = mpf_get_str(nullptr, &e, 10, 1, m_data);
|
|
491
|
+
--e;
|
|
492
|
+
unsigned offset = *ps == '-' ? 1 : 0;
|
|
493
|
+
ps[offset] = '0';
|
|
494
|
+
ps[offset + 1] = 0;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
result = ps;
|
|
498
|
+
(*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
|
|
499
|
+
}
|
|
500
|
+
boost::multiprecision::detail::format_float_string(result, e, org_digits, f, mpf_sgn(m_data) == 0);
|
|
501
|
+
return result;
|
|
502
|
+
}
|
|
503
|
+
~gmp_float_imp() noexcept
|
|
504
|
+
{
|
|
505
|
+
if (m_data[0]._mp_d)
|
|
506
|
+
{
|
|
507
|
+
mpf_clear(m_data);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
void negate() noexcept
|
|
511
|
+
{
|
|
512
|
+
BOOST_MP_ASSERT(m_data[0]._mp_d);
|
|
513
|
+
mpf_neg(m_data, m_data);
|
|
514
|
+
}
|
|
515
|
+
int compare(const gmp_float<digits10>& o) const noexcept
|
|
516
|
+
{
|
|
517
|
+
BOOST_MP_ASSERT(m_data[0]._mp_d && o.m_data[0]._mp_d);
|
|
518
|
+
return mpf_cmp(m_data, o.m_data);
|
|
519
|
+
}
|
|
520
|
+
int compare(long i) const noexcept
|
|
521
|
+
{
|
|
522
|
+
BOOST_MP_ASSERT(m_data[0]._mp_d);
|
|
523
|
+
return mpf_cmp_si(m_data, i);
|
|
524
|
+
}
|
|
525
|
+
int compare(unsigned long i) const noexcept
|
|
526
|
+
{
|
|
527
|
+
BOOST_MP_ASSERT(m_data[0]._mp_d);
|
|
528
|
+
return mpf_cmp_ui(m_data, i);
|
|
529
|
+
}
|
|
530
|
+
template <class V>
|
|
531
|
+
typename std::enable_if<boost::multiprecision::detail::is_arithmetic<V>::value, int>::type compare(V v) const
|
|
532
|
+
{
|
|
533
|
+
gmp_float<digits10> d;
|
|
534
|
+
d = v;
|
|
535
|
+
return compare(d);
|
|
536
|
+
}
|
|
537
|
+
mpf_t& data() noexcept
|
|
538
|
+
{
|
|
539
|
+
BOOST_MP_ASSERT(m_data[0]._mp_d);
|
|
540
|
+
return m_data;
|
|
541
|
+
}
|
|
542
|
+
const mpf_t& data() const noexcept
|
|
543
|
+
{
|
|
544
|
+
BOOST_MP_ASSERT(m_data[0]._mp_d);
|
|
545
|
+
return m_data;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
protected:
|
|
549
|
+
mpf_t m_data;
|
|
550
|
+
static unsigned& get_default_precision() noexcept
|
|
551
|
+
{
|
|
552
|
+
static BOOST_MP_THREAD_LOCAL unsigned val(get_global_default_precision());
|
|
553
|
+
return val;
|
|
554
|
+
}
|
|
555
|
+
static boost::multiprecision::detail::precision_type& get_global_default_precision() noexcept
|
|
556
|
+
{
|
|
557
|
+
static boost::multiprecision::detail::precision_type val(50);
|
|
558
|
+
return val;
|
|
559
|
+
}
|
|
560
|
+
#ifndef BOOST_MT_NO_ATOMIC_INT
|
|
561
|
+
static std::atomic<variable_precision_options>& get_global_default_options() noexcept
|
|
562
|
+
#else
|
|
563
|
+
static variable_precision_options& get_global_default_options() noexcept
|
|
564
|
+
#endif
|
|
565
|
+
{
|
|
566
|
+
#ifndef BOOST_MT_NO_ATOMIC_INT
|
|
567
|
+
static std::atomic<variable_precision_options> val{variable_precision_options::preserve_related_precision};
|
|
568
|
+
#else
|
|
569
|
+
static variable_precision_options val{variable_precision_options::preserve_related_precision};
|
|
570
|
+
#endif
|
|
571
|
+
return val;
|
|
572
|
+
}
|
|
573
|
+
static variable_precision_options& get_default_options()noexcept
|
|
574
|
+
{
|
|
575
|
+
static BOOST_MP_THREAD_LOCAL variable_precision_options val(get_global_default_options());
|
|
576
|
+
return val;
|
|
577
|
+
}
|
|
578
|
+
static bool preserve_source_precision() noexcept
|
|
579
|
+
{
|
|
580
|
+
return get_default_options() >= variable_precision_options::preserve_source_precision;
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
class gmp_char_ptr
|
|
585
|
+
{
|
|
586
|
+
private:
|
|
587
|
+
char* ptr_val;
|
|
588
|
+
void* (*alloc_func_ptr)(size_t);
|
|
589
|
+
void* (*realloc_func_ptr)(void*, size_t, size_t);
|
|
590
|
+
void (*free_func_ptr)(void*, size_t);
|
|
591
|
+
|
|
592
|
+
public:
|
|
593
|
+
gmp_char_ptr() = delete;
|
|
594
|
+
explicit gmp_char_ptr(char* val_) : ptr_val {val_}
|
|
595
|
+
{
|
|
596
|
+
mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
|
|
597
|
+
}
|
|
598
|
+
~gmp_char_ptr() noexcept
|
|
599
|
+
{
|
|
600
|
+
(*free_func_ptr)((void*)ptr_val, sizeof(*ptr_val));
|
|
601
|
+
ptr_val = nullptr;
|
|
602
|
+
}
|
|
603
|
+
inline char* get() noexcept { return ptr_val; }
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
} // namespace detail
|
|
607
|
+
|
|
608
|
+
template <unsigned digits10>
|
|
609
|
+
struct gmp_float : public detail::gmp_float_imp<digits10>
|
|
610
|
+
{
|
|
611
|
+
gmp_float()
|
|
612
|
+
{
|
|
613
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
|
614
|
+
}
|
|
615
|
+
gmp_float(const gmp_float& o) : detail::gmp_float_imp<digits10>(o) {}
|
|
616
|
+
template <unsigned D>
|
|
617
|
+
gmp_float(const gmp_float<D>& o, typename std::enable_if<D <= digits10>::type* = nullptr);
|
|
618
|
+
template <unsigned D>
|
|
619
|
+
explicit gmp_float(const gmp_float<D>& o, typename std::enable_if<!(D <= digits10)>::type* = nullptr);
|
|
620
|
+
gmp_float(const gmp_int& o);
|
|
621
|
+
gmp_float(const gmp_rational& o);
|
|
622
|
+
gmp_float(const mpf_t val)
|
|
623
|
+
{
|
|
624
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
|
625
|
+
mpf_set(this->m_data, val);
|
|
626
|
+
}
|
|
627
|
+
gmp_float(const mpz_t val)
|
|
628
|
+
{
|
|
629
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
|
630
|
+
mpf_set_z(this->m_data, val);
|
|
631
|
+
}
|
|
632
|
+
gmp_float(const mpq_t val)
|
|
633
|
+
{
|
|
634
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
|
635
|
+
mpf_set_q(this->m_data, val);
|
|
636
|
+
}
|
|
637
|
+
// rvalue copy
|
|
638
|
+
gmp_float(gmp_float&& o) noexcept : detail::gmp_float_imp<digits10>(static_cast<detail::gmp_float_imp<digits10>&&>(o))
|
|
639
|
+
{}
|
|
640
|
+
gmp_float& operator=(const gmp_float& o)
|
|
641
|
+
{
|
|
642
|
+
*static_cast<detail::gmp_float_imp<digits10>*>(this) = static_cast<detail::gmp_float_imp<digits10> const&>(o);
|
|
643
|
+
return *this;
|
|
644
|
+
}
|
|
645
|
+
gmp_float& operator=(gmp_float&& o) noexcept
|
|
646
|
+
{
|
|
647
|
+
*static_cast<detail::gmp_float_imp<digits10>*>(this) = static_cast<detail::gmp_float_imp<digits10>&&>(o);
|
|
648
|
+
return *this;
|
|
649
|
+
}
|
|
650
|
+
template <unsigned D>
|
|
651
|
+
gmp_float& operator=(const gmp_float<D>& o);
|
|
652
|
+
gmp_float& operator=(const gmp_int& o);
|
|
653
|
+
gmp_float& operator=(const gmp_rational& o);
|
|
654
|
+
gmp_float& operator=(const mpf_t val)
|
|
655
|
+
{
|
|
656
|
+
if (this->m_data[0]._mp_d == nullptr)
|
|
657
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
|
658
|
+
mpf_set(this->m_data, val);
|
|
659
|
+
return *this;
|
|
660
|
+
}
|
|
661
|
+
gmp_float& operator=(const mpz_t val)
|
|
662
|
+
{
|
|
663
|
+
if (this->m_data[0]._mp_d == nullptr)
|
|
664
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
|
665
|
+
mpf_set_z(this->m_data, val);
|
|
666
|
+
return *this;
|
|
667
|
+
}
|
|
668
|
+
gmp_float& operator=(const mpq_t val)
|
|
669
|
+
{
|
|
670
|
+
if (this->m_data[0]._mp_d == nullptr)
|
|
671
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
|
672
|
+
mpf_set_q(this->m_data, val);
|
|
673
|
+
return *this;
|
|
674
|
+
}
|
|
675
|
+
template <class V>
|
|
676
|
+
typename std::enable_if<std::is_assignable<detail::gmp_float_imp<digits10>, V>::value, gmp_float&>::type operator=(const V& v)
|
|
677
|
+
{
|
|
678
|
+
*static_cast<detail::gmp_float_imp<digits10>*>(this) = v;
|
|
679
|
+
return *this;
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
template <>
|
|
684
|
+
struct gmp_float<0> : public detail::gmp_float_imp<0>
|
|
685
|
+
{
|
|
686
|
+
//
|
|
687
|
+
// We have a problem with mpf_t in that the precision we request isn't what we get.
|
|
688
|
+
// As a result the front end can end up chasing it's tail trying to create a variable
|
|
689
|
+
// with the the correct precision to hold the result of an expression.
|
|
690
|
+
// See: https://github.com/boostorg/multiprecision/issues/164
|
|
691
|
+
// The problem is made worse by the fact that our conversions from base10 to 2 and
|
|
692
|
+
// vice-versa do not exactly round trip (and probably never will).
|
|
693
|
+
// The workaround is to keep track of the precision requested, and always return
|
|
694
|
+
// that as the current actual precision.
|
|
695
|
+
//
|
|
696
|
+
private:
|
|
697
|
+
unsigned requested_precision;
|
|
698
|
+
|
|
699
|
+
public:
|
|
700
|
+
gmp_float() : requested_precision(get_default_precision())
|
|
701
|
+
{
|
|
702
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
|
|
703
|
+
}
|
|
704
|
+
gmp_float(const mpf_t val) : requested_precision(get_default_precision())
|
|
705
|
+
{
|
|
706
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
|
|
707
|
+
mpf_set(this->m_data, val);
|
|
708
|
+
}
|
|
709
|
+
gmp_float(const mpz_t val) : requested_precision(get_default_precision())
|
|
710
|
+
{
|
|
711
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
|
|
712
|
+
mpf_set_z(this->m_data, val);
|
|
713
|
+
}
|
|
714
|
+
gmp_float(const mpq_t val) : requested_precision(get_default_precision())
|
|
715
|
+
{
|
|
716
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
|
|
717
|
+
mpf_set_q(this->m_data, val);
|
|
718
|
+
}
|
|
719
|
+
gmp_float(const gmp_float& o) : detail::gmp_float_imp<0>(o), requested_precision(preserve_source_precision() ? o.requested_precision : get_default_precision()) {}
|
|
720
|
+
template <unsigned D>
|
|
721
|
+
gmp_float(const gmp_float<D>& o)
|
|
722
|
+
{
|
|
723
|
+
mpf_init2(this->m_data, preserve_related_precision() ? mpf_get_prec(o.data()) : multiprecision::detail::digits10_2_2(get_default_precision()));
|
|
724
|
+
mpf_set(this->m_data, o.data());
|
|
725
|
+
requested_precision = preserve_related_precision() ? D : get_default_precision();
|
|
726
|
+
}
|
|
727
|
+
// rvalue copy
|
|
728
|
+
gmp_float(gmp_float&& o) noexcept : detail::gmp_float_imp<0>(static_cast<detail::gmp_float_imp<0>&&>(o)), requested_precision((this->get_default_options() != variable_precision_options::preserve_target_precision) ? o.requested_precision : get_default_precision())
|
|
729
|
+
{}
|
|
730
|
+
gmp_float(const gmp_int& o);
|
|
731
|
+
gmp_float(const gmp_rational& o);
|
|
732
|
+
gmp_float(const gmp_float& o, unsigned digits10) : requested_precision(digits10)
|
|
733
|
+
{
|
|
734
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
|
735
|
+
mpf_set(this->m_data, o.data());
|
|
736
|
+
}
|
|
737
|
+
template <class V>
|
|
738
|
+
gmp_float(const V& o, unsigned digits10) : requested_precision(digits10)
|
|
739
|
+
{
|
|
740
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
|
741
|
+
*this = o;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
|
|
745
|
+
//
|
|
746
|
+
// Support for new types in C++17
|
|
747
|
+
//
|
|
748
|
+
template <class Traits>
|
|
749
|
+
gmp_float(const std::basic_string_view<char, Traits>& o, unsigned digits10) : requested_precision(digits10)
|
|
750
|
+
{
|
|
751
|
+
using default_ops::assign_from_string_view;
|
|
752
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(digits10));
|
|
753
|
+
assign_from_string_view(*this, o);
|
|
754
|
+
}
|
|
755
|
+
#endif
|
|
756
|
+
gmp_float& operator=(const gmp_float& o)
|
|
757
|
+
{
|
|
758
|
+
*static_cast<detail::gmp_float_imp<0>*>(this) = static_cast<detail::gmp_float_imp<0> const&>(o);
|
|
759
|
+
if(preserve_source_precision())
|
|
760
|
+
requested_precision = o.requested_precision;
|
|
761
|
+
return *this;
|
|
762
|
+
}
|
|
763
|
+
// rvalue copy
|
|
764
|
+
gmp_float& operator=(gmp_float&& o) noexcept
|
|
765
|
+
{
|
|
766
|
+
*static_cast<detail::gmp_float_imp<0>*>(this) = static_cast<detail::gmp_float_imp<0>&&>(o);
|
|
767
|
+
if ((this->get_default_options() != variable_precision_options::preserve_target_precision))
|
|
768
|
+
requested_precision = o.requested_precision;
|
|
769
|
+
return *this;
|
|
770
|
+
}
|
|
771
|
+
template <unsigned D>
|
|
772
|
+
gmp_float& operator=(const gmp_float<D>& o)
|
|
773
|
+
{
|
|
774
|
+
if (this->m_data[0]._mp_d == nullptr)
|
|
775
|
+
{
|
|
776
|
+
mpf_init2(this->m_data, preserve_related_precision() ? mpf_get_prec(o.data()) : multiprecision::detail::digits10_2_2(get_default_precision()));
|
|
777
|
+
}
|
|
778
|
+
else if(preserve_related_precision())
|
|
779
|
+
{
|
|
780
|
+
mpf_set_prec(this->m_data, mpf_get_prec(o.data()));
|
|
781
|
+
}
|
|
782
|
+
mpf_set(this->m_data, o.data());
|
|
783
|
+
if (preserve_related_precision())
|
|
784
|
+
requested_precision = D;
|
|
785
|
+
return *this;
|
|
786
|
+
}
|
|
787
|
+
gmp_float& operator=(const gmp_int& o);
|
|
788
|
+
gmp_float& operator=(const gmp_rational& o);
|
|
789
|
+
gmp_float& operator=(const mpf_t val)
|
|
790
|
+
{
|
|
791
|
+
if (this->m_data[0]._mp_d == nullptr)
|
|
792
|
+
{
|
|
793
|
+
requested_precision = get_default_precision();
|
|
794
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
|
|
795
|
+
}
|
|
796
|
+
mpf_set(this->m_data, val);
|
|
797
|
+
return *this;
|
|
798
|
+
}
|
|
799
|
+
gmp_float& operator=(const mpz_t val)
|
|
800
|
+
{
|
|
801
|
+
if (this->m_data[0]._mp_d == nullptr)
|
|
802
|
+
{
|
|
803
|
+
requested_precision = get_default_precision();
|
|
804
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
|
|
805
|
+
}
|
|
806
|
+
mpf_set_z(this->m_data, val);
|
|
807
|
+
return *this;
|
|
808
|
+
}
|
|
809
|
+
gmp_float& operator=(const mpq_t val)
|
|
810
|
+
{
|
|
811
|
+
if (this->m_data[0]._mp_d == nullptr)
|
|
812
|
+
{
|
|
813
|
+
requested_precision = get_default_precision();
|
|
814
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
|
|
815
|
+
}
|
|
816
|
+
mpf_set_q(this->m_data, val);
|
|
817
|
+
return *this;
|
|
818
|
+
}
|
|
819
|
+
template <class V>
|
|
820
|
+
typename std::enable_if<std::is_assignable<detail::gmp_float_imp<0>, V>::value, gmp_float&>::type operator=(const V& v)
|
|
821
|
+
{
|
|
822
|
+
constexpr unsigned d10 = std::is_floating_point<V>::value ?
|
|
823
|
+
std::numeric_limits<V>::digits10 :
|
|
824
|
+
std::numeric_limits<V>::digits10 ? 1 + std::numeric_limits<V>::digits10 :
|
|
825
|
+
1 + boost::multiprecision::detail::digits2_2_10(std::numeric_limits<V>::digits);
|
|
826
|
+
if((thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision) && (precision() < d10))
|
|
827
|
+
this->precision(d10);
|
|
828
|
+
*static_cast<detail::gmp_float_imp<0>*>(this) = v;
|
|
829
|
+
return *this;
|
|
830
|
+
}
|
|
831
|
+
static unsigned default_precision() noexcept
|
|
832
|
+
{
|
|
833
|
+
return get_global_default_precision();
|
|
834
|
+
}
|
|
835
|
+
static void default_precision(unsigned v) noexcept
|
|
836
|
+
{
|
|
837
|
+
get_global_default_precision() = v;
|
|
838
|
+
}
|
|
839
|
+
static unsigned thread_default_precision() noexcept
|
|
840
|
+
{
|
|
841
|
+
return get_default_precision();
|
|
842
|
+
}
|
|
843
|
+
static void thread_default_precision(unsigned v) noexcept
|
|
844
|
+
{
|
|
845
|
+
get_default_precision() = v;
|
|
846
|
+
}
|
|
847
|
+
unsigned precision() const noexcept
|
|
848
|
+
{
|
|
849
|
+
return requested_precision;
|
|
850
|
+
}
|
|
851
|
+
void precision(unsigned digits10) noexcept
|
|
852
|
+
{
|
|
853
|
+
requested_precision = digits10;
|
|
854
|
+
mpf_set_prec(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
|
|
855
|
+
}
|
|
856
|
+
//
|
|
857
|
+
// Variable precision options:
|
|
858
|
+
//
|
|
859
|
+
static variable_precision_options default_variable_precision_options()noexcept
|
|
860
|
+
{
|
|
861
|
+
return get_global_default_options();
|
|
862
|
+
}
|
|
863
|
+
static variable_precision_options thread_default_variable_precision_options()noexcept
|
|
864
|
+
{
|
|
865
|
+
return get_default_options();
|
|
866
|
+
}
|
|
867
|
+
static void default_variable_precision_options(variable_precision_options opts)
|
|
868
|
+
{
|
|
869
|
+
get_global_default_options() = opts;
|
|
870
|
+
}
|
|
871
|
+
static void thread_default_variable_precision_options(variable_precision_options opts)
|
|
872
|
+
{
|
|
873
|
+
get_default_options() = opts;
|
|
874
|
+
}
|
|
875
|
+
static bool preserve_source_precision()
|
|
876
|
+
{
|
|
877
|
+
return get_default_options() >= variable_precision_options::preserve_source_precision;
|
|
878
|
+
}
|
|
879
|
+
static bool preserve_related_precision()
|
|
880
|
+
{
|
|
881
|
+
return get_default_options() >= variable_precision_options::preserve_related_precision;
|
|
882
|
+
}
|
|
883
|
+
static bool preserve_all_precision()
|
|
884
|
+
{
|
|
885
|
+
return get_default_options() >= variable_precision_options::preserve_all_precision;
|
|
886
|
+
}
|
|
887
|
+
//
|
|
888
|
+
// swap:
|
|
889
|
+
//
|
|
890
|
+
void swap(gmp_float& o)
|
|
891
|
+
{
|
|
892
|
+
std::swap(requested_precision, o.requested_precision);
|
|
893
|
+
gmp_float_imp<0>::swap(o);
|
|
894
|
+
}
|
|
895
|
+
};
|
|
896
|
+
|
|
897
|
+
template <unsigned digits10, class T>
|
|
898
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_eq(const gmp_float<digits10>& a, const T& b) noexcept
|
|
899
|
+
{
|
|
900
|
+
return a.compare(b) == 0;
|
|
901
|
+
}
|
|
902
|
+
template <unsigned digits10, class T>
|
|
903
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_lt(const gmp_float<digits10>& a, const T& b) noexcept
|
|
904
|
+
{
|
|
905
|
+
return a.compare(b) < 0;
|
|
906
|
+
}
|
|
907
|
+
template <unsigned digits10, class T>
|
|
908
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_gt(const gmp_float<digits10>& a, const T& b) noexcept
|
|
909
|
+
{
|
|
910
|
+
return a.compare(b) > 0;
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
template <unsigned D1, unsigned D2>
|
|
914
|
+
inline void eval_add(gmp_float<D1>& result, const gmp_float<D2>& o)
|
|
915
|
+
{
|
|
916
|
+
mpf_add(result.data(), result.data(), o.data());
|
|
917
|
+
}
|
|
918
|
+
template <unsigned D1, unsigned D2>
|
|
919
|
+
inline void eval_subtract(gmp_float<D1>& result, const gmp_float<D2>& o)
|
|
920
|
+
{
|
|
921
|
+
mpf_sub(result.data(), result.data(), o.data());
|
|
922
|
+
}
|
|
923
|
+
template <unsigned D1, unsigned D2>
|
|
924
|
+
inline void eval_multiply(gmp_float<D1>& result, const gmp_float<D2>& o)
|
|
925
|
+
{
|
|
926
|
+
mpf_mul(result.data(), result.data(), o.data());
|
|
927
|
+
}
|
|
928
|
+
template <unsigned digits10>
|
|
929
|
+
inline bool eval_is_zero(const gmp_float<digits10>& val) noexcept
|
|
930
|
+
{
|
|
931
|
+
return mpf_sgn(val.data()) == 0;
|
|
932
|
+
}
|
|
933
|
+
template <unsigned D1, unsigned D2>
|
|
934
|
+
inline void eval_divide(gmp_float<D1>& result, const gmp_float<D2>& o)
|
|
935
|
+
{
|
|
936
|
+
if (eval_is_zero(o))
|
|
937
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
938
|
+
mpf_div(result.data(), result.data(), o.data());
|
|
939
|
+
}
|
|
940
|
+
template <unsigned digits10>
|
|
941
|
+
inline void eval_add(gmp_float<digits10>& result, unsigned long i)
|
|
942
|
+
{
|
|
943
|
+
mpf_add_ui(result.data(), result.data(), i);
|
|
944
|
+
}
|
|
945
|
+
template <unsigned digits10>
|
|
946
|
+
inline void eval_subtract(gmp_float<digits10>& result, unsigned long i)
|
|
947
|
+
{
|
|
948
|
+
mpf_sub_ui(result.data(), result.data(), i);
|
|
949
|
+
}
|
|
950
|
+
template <unsigned digits10>
|
|
951
|
+
inline void eval_multiply(gmp_float<digits10>& result, unsigned long i)
|
|
952
|
+
{
|
|
953
|
+
mpf_mul_ui(result.data(), result.data(), i);
|
|
954
|
+
}
|
|
955
|
+
template <unsigned digits10>
|
|
956
|
+
inline void eval_divide(gmp_float<digits10>& result, unsigned long i)
|
|
957
|
+
{
|
|
958
|
+
if (i == 0)
|
|
959
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
960
|
+
mpf_div_ui(result.data(), result.data(), i);
|
|
961
|
+
}
|
|
962
|
+
template <unsigned digits10>
|
|
963
|
+
inline void eval_add(gmp_float<digits10>& result, long i)
|
|
964
|
+
{
|
|
965
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
966
|
+
|
|
967
|
+
if (i > 0)
|
|
968
|
+
mpf_add_ui(result.data(), result.data(), static_cast<local_uint_type>(i));
|
|
969
|
+
else if (i < 0)
|
|
970
|
+
mpf_sub_ui(result.data(), result.data(), static_cast<local_uint_type>(-i));
|
|
971
|
+
}
|
|
972
|
+
template <unsigned digits10>
|
|
973
|
+
inline void eval_subtract(gmp_float<digits10>& result, long i)
|
|
974
|
+
{
|
|
975
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
976
|
+
|
|
977
|
+
if (i > 0)
|
|
978
|
+
mpf_sub_ui(result.data(), result.data(), static_cast<local_uint_type>(i));
|
|
979
|
+
else if (i < 0)
|
|
980
|
+
mpf_add_ui(result.data(), result.data(), static_cast<local_uint_type>(-i));
|
|
981
|
+
}
|
|
982
|
+
template <unsigned digits10>
|
|
983
|
+
inline void eval_multiply(gmp_float<digits10>& result, long i)
|
|
984
|
+
{
|
|
985
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
986
|
+
|
|
987
|
+
mpf_mul_ui(result.data(), result.data(), static_cast<local_uint_type>(boost::multiprecision::detail::unsigned_abs(i)));
|
|
988
|
+
|
|
989
|
+
if (i < 0)
|
|
990
|
+
mpf_neg(result.data(), result.data());
|
|
991
|
+
}
|
|
992
|
+
template <unsigned digits10>
|
|
993
|
+
inline void eval_divide(gmp_float<digits10>& result, long i)
|
|
994
|
+
{
|
|
995
|
+
if (i == 0)
|
|
996
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
997
|
+
|
|
998
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
999
|
+
|
|
1000
|
+
mpf_div_ui(result.data(), result.data(), static_cast<local_uint_type>(boost::multiprecision::detail::unsigned_abs(i)));
|
|
1001
|
+
|
|
1002
|
+
if (i < 0)
|
|
1003
|
+
mpf_neg(result.data(), result.data());
|
|
1004
|
+
}
|
|
1005
|
+
//
|
|
1006
|
+
// Specialised 3 arg versions of the basic operators:
|
|
1007
|
+
//
|
|
1008
|
+
template <unsigned D1, unsigned D2, unsigned D3>
|
|
1009
|
+
inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
|
|
1010
|
+
{
|
|
1011
|
+
mpf_add(a.data(), x.data(), y.data());
|
|
1012
|
+
}
|
|
1013
|
+
template <unsigned D1, unsigned D2>
|
|
1014
|
+
inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
|
|
1015
|
+
{
|
|
1016
|
+
mpf_add_ui(a.data(), x.data(), y);
|
|
1017
|
+
}
|
|
1018
|
+
template <unsigned D1, unsigned D2>
|
|
1019
|
+
inline void eval_add(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
|
|
1020
|
+
{
|
|
1021
|
+
if (y < 0)
|
|
1022
|
+
mpf_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
|
|
1023
|
+
else
|
|
1024
|
+
mpf_add_ui(a.data(), x.data(), y);
|
|
1025
|
+
}
|
|
1026
|
+
template <unsigned D1, unsigned D2>
|
|
1027
|
+
inline void eval_add(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
|
|
1028
|
+
{
|
|
1029
|
+
mpf_add_ui(a.data(), y.data(), x);
|
|
1030
|
+
}
|
|
1031
|
+
template <unsigned D1, unsigned D2>
|
|
1032
|
+
inline void eval_add(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
|
|
1033
|
+
{
|
|
1034
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
1035
|
+
|
|
1036
|
+
if (x < 0)
|
|
1037
|
+
{
|
|
1038
|
+
mpf_ui_sub(a.data(), static_cast<local_uint_type>(-x), y.data());
|
|
1039
|
+
mpf_neg(a.data(), a.data());
|
|
1040
|
+
}
|
|
1041
|
+
else
|
|
1042
|
+
mpf_add_ui(a.data(), y.data(), static_cast<local_uint_type>(x));
|
|
1043
|
+
}
|
|
1044
|
+
template <unsigned D1, unsigned D2, unsigned D3>
|
|
1045
|
+
inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
|
|
1046
|
+
{
|
|
1047
|
+
mpf_sub(a.data(), x.data(), y.data());
|
|
1048
|
+
}
|
|
1049
|
+
template <unsigned D1, unsigned D2>
|
|
1050
|
+
inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
|
|
1051
|
+
{
|
|
1052
|
+
mpf_sub_ui(a.data(), x.data(), y);
|
|
1053
|
+
}
|
|
1054
|
+
template <unsigned D1, unsigned D2>
|
|
1055
|
+
inline void eval_subtract(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
|
|
1056
|
+
{
|
|
1057
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
1058
|
+
|
|
1059
|
+
if (y < 0)
|
|
1060
|
+
mpf_add_ui(a.data(), x.data(), static_cast<local_uint_type>(-y));
|
|
1061
|
+
else
|
|
1062
|
+
mpf_sub_ui(a.data(), x.data(), static_cast<local_uint_type>(y));
|
|
1063
|
+
}
|
|
1064
|
+
template <unsigned D1, unsigned D2>
|
|
1065
|
+
inline void eval_subtract(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
|
|
1066
|
+
{
|
|
1067
|
+
mpf_ui_sub(a.data(), x, y.data());
|
|
1068
|
+
}
|
|
1069
|
+
template <unsigned D1, unsigned D2>
|
|
1070
|
+
inline void eval_subtract(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
|
|
1071
|
+
{
|
|
1072
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
1073
|
+
|
|
1074
|
+
if (x < 0)
|
|
1075
|
+
{
|
|
1076
|
+
mpf_add_ui(a.data(), y.data(), static_cast<local_uint_type>(-x));
|
|
1077
|
+
mpf_neg(a.data(), a.data());
|
|
1078
|
+
}
|
|
1079
|
+
else
|
|
1080
|
+
mpf_ui_sub(a.data(), static_cast<local_uint_type>(x), y.data());
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
template <unsigned D1, unsigned D2, unsigned D3>
|
|
1084
|
+
inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
|
|
1085
|
+
{
|
|
1086
|
+
mpf_mul(a.data(), x.data(), y.data());
|
|
1087
|
+
}
|
|
1088
|
+
template <unsigned D1, unsigned D2>
|
|
1089
|
+
inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
|
|
1090
|
+
{
|
|
1091
|
+
mpf_mul_ui(a.data(), x.data(), y);
|
|
1092
|
+
}
|
|
1093
|
+
template <unsigned D1, unsigned D2>
|
|
1094
|
+
inline void eval_multiply(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
|
|
1095
|
+
{
|
|
1096
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
1097
|
+
|
|
1098
|
+
if (y < 0)
|
|
1099
|
+
{
|
|
1100
|
+
mpf_mul_ui(a.data(), x.data(), static_cast<local_uint_type>(-y));
|
|
1101
|
+
a.negate();
|
|
1102
|
+
}
|
|
1103
|
+
else
|
|
1104
|
+
mpf_mul_ui(a.data(), x.data(), static_cast<local_uint_type>(y));
|
|
1105
|
+
}
|
|
1106
|
+
template <unsigned D1, unsigned D2>
|
|
1107
|
+
inline void eval_multiply(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
|
|
1108
|
+
{
|
|
1109
|
+
mpf_mul_ui(a.data(), y.data(), x);
|
|
1110
|
+
}
|
|
1111
|
+
template <unsigned D1, unsigned D2>
|
|
1112
|
+
inline void eval_multiply(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
|
|
1113
|
+
{
|
|
1114
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
1115
|
+
|
|
1116
|
+
if (x < 0)
|
|
1117
|
+
{
|
|
1118
|
+
mpf_mul_ui(a.data(), y.data(), static_cast<local_uint_type>(-x));
|
|
1119
|
+
mpf_neg(a.data(), a.data());
|
|
1120
|
+
}
|
|
1121
|
+
else
|
|
1122
|
+
mpf_mul_ui(a.data(), y.data(), static_cast<local_uint_type>(x));
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
template <unsigned D1, unsigned D2, unsigned D3>
|
|
1126
|
+
inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, const gmp_float<D3>& y)
|
|
1127
|
+
{
|
|
1128
|
+
if (eval_is_zero(y))
|
|
1129
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
1130
|
+
mpf_div(a.data(), x.data(), y.data());
|
|
1131
|
+
}
|
|
1132
|
+
template <unsigned D1, unsigned D2>
|
|
1133
|
+
inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, unsigned long y)
|
|
1134
|
+
{
|
|
1135
|
+
if (y == 0)
|
|
1136
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
1137
|
+
mpf_div_ui(a.data(), x.data(), y);
|
|
1138
|
+
}
|
|
1139
|
+
template <unsigned D1, unsigned D2>
|
|
1140
|
+
inline void eval_divide(gmp_float<D1>& a, const gmp_float<D2>& x, long y)
|
|
1141
|
+
{
|
|
1142
|
+
if (y == 0)
|
|
1143
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
1144
|
+
|
|
1145
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
1146
|
+
|
|
1147
|
+
if (y < 0)
|
|
1148
|
+
{
|
|
1149
|
+
mpf_div_ui(a.data(), x.data(), static_cast<local_uint_type>(-y));
|
|
1150
|
+
a.negate();
|
|
1151
|
+
}
|
|
1152
|
+
else
|
|
1153
|
+
mpf_div_ui(a.data(), x.data(), static_cast<local_uint_type>(y));
|
|
1154
|
+
}
|
|
1155
|
+
template <unsigned D1, unsigned D2>
|
|
1156
|
+
inline void eval_divide(gmp_float<D1>& a, unsigned long x, const gmp_float<D2>& y)
|
|
1157
|
+
{
|
|
1158
|
+
if (eval_is_zero(y))
|
|
1159
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
1160
|
+
mpf_ui_div(a.data(), x, y.data());
|
|
1161
|
+
}
|
|
1162
|
+
template <unsigned D1, unsigned D2>
|
|
1163
|
+
inline void eval_divide(gmp_float<D1>& a, long x, const gmp_float<D2>& y)
|
|
1164
|
+
{
|
|
1165
|
+
if (eval_is_zero(y))
|
|
1166
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
1167
|
+
if (x < 0)
|
|
1168
|
+
{
|
|
1169
|
+
mpf_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
|
|
1170
|
+
mpf_neg(a.data(), a.data());
|
|
1171
|
+
}
|
|
1172
|
+
else
|
|
1173
|
+
{
|
|
1174
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
1175
|
+
|
|
1176
|
+
mpf_ui_div(a.data(), static_cast<local_uint_type>(x), y.data());
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
template <unsigned digits10>
|
|
1181
|
+
inline int eval_get_sign(const gmp_float<digits10>& val) noexcept
|
|
1182
|
+
{
|
|
1183
|
+
return mpf_sgn(val.data());
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
template <unsigned digits10>
|
|
1187
|
+
inline void eval_convert_to(unsigned long* result, const gmp_float<digits10>& val) noexcept
|
|
1188
|
+
{
|
|
1189
|
+
if (0 == mpf_fits_ulong_p(val.data()))
|
|
1190
|
+
*result = (std::numeric_limits<unsigned long>::max)();
|
|
1191
|
+
else
|
|
1192
|
+
*result = static_cast<unsigned long>(mpf_get_ui(val.data()));
|
|
1193
|
+
}
|
|
1194
|
+
template <unsigned digits10>
|
|
1195
|
+
inline void eval_convert_to(long* result, const gmp_float<digits10>& val) noexcept
|
|
1196
|
+
{
|
|
1197
|
+
if (0 == mpf_fits_slong_p(val.data()))
|
|
1198
|
+
{
|
|
1199
|
+
*result = (std::numeric_limits<long>::max)();
|
|
1200
|
+
*result *= mpf_sgn(val.data());
|
|
1201
|
+
}
|
|
1202
|
+
else
|
|
1203
|
+
*result = static_cast<long>(mpf_get_si(val.data()));
|
|
1204
|
+
}
|
|
1205
|
+
#ifdef BOOST_MP_STANDALONE
|
|
1206
|
+
template <unsigned digits10>
|
|
1207
|
+
inline void eval_convert_to(long double* result, const gmp_float<digits10>& val) noexcept
|
|
1208
|
+
{
|
|
1209
|
+
mp_exp_t exp = 0;
|
|
1210
|
+
|
|
1211
|
+
detail::gmp_char_ptr val_char_ptr {mpf_get_str(nullptr, &exp, 10, LDBL_DIG, val.data())};
|
|
1212
|
+
|
|
1213
|
+
auto temp_string = std::string(val_char_ptr.get());
|
|
1214
|
+
if(exp > 0 && static_cast<std::size_t>(exp) < temp_string.size())
|
|
1215
|
+
{
|
|
1216
|
+
if(temp_string.front() == '-')
|
|
1217
|
+
{
|
|
1218
|
+
++exp;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
temp_string.insert(static_cast<std::size_t>(exp), static_cast<std::size_t>(1u), '.');
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
*result = std::strtold(temp_string.c_str(), nullptr);
|
|
1225
|
+
|
|
1226
|
+
if((temp_string.size() == 2ul && *result < 0.0l) ||
|
|
1227
|
+
(static_cast<std::size_t>(exp) > temp_string.size()))
|
|
1228
|
+
{
|
|
1229
|
+
*result *= std::pow(10l, exp-1);
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
#endif // BOOST_MP_STANDALONE
|
|
1233
|
+
template <unsigned digits10>
|
|
1234
|
+
inline void eval_convert_to(double* result, const gmp_float<digits10>& val) noexcept
|
|
1235
|
+
{
|
|
1236
|
+
*result = mpf_get_d(val.data());
|
|
1237
|
+
}
|
|
1238
|
+
#ifdef BOOST_HAS_LONG_LONG
|
|
1239
|
+
template <unsigned digits10>
|
|
1240
|
+
inline void eval_convert_to(long long* result, const gmp_float<digits10>& val)
|
|
1241
|
+
{
|
|
1242
|
+
gmp_float<digits10> t(val);
|
|
1243
|
+
if (eval_get_sign(t) < 0)
|
|
1244
|
+
t.negate();
|
|
1245
|
+
|
|
1246
|
+
long digits = std::numeric_limits<long long>::digits - std::numeric_limits<long>::digits;
|
|
1247
|
+
|
|
1248
|
+
if (digits > 0)
|
|
1249
|
+
mpf_div_2exp(t.data(), t.data(), digits);
|
|
1250
|
+
|
|
1251
|
+
if (!mpf_fits_slong_p(t.data()))
|
|
1252
|
+
{
|
|
1253
|
+
if (eval_get_sign(val) < 0)
|
|
1254
|
+
*result = (std::numeric_limits<long long>::min)();
|
|
1255
|
+
else
|
|
1256
|
+
*result = (std::numeric_limits<long long>::max)();
|
|
1257
|
+
return;
|
|
1258
|
+
};
|
|
1259
|
+
|
|
1260
|
+
*result = mpf_get_si(t.data());
|
|
1261
|
+
while (digits > 0)
|
|
1262
|
+
{
|
|
1263
|
+
*result <<= digits;
|
|
1264
|
+
digits -= std::numeric_limits<unsigned long>::digits;
|
|
1265
|
+
mpf_mul_2exp(t.data(), t.data(), digits >= 0 ? std::numeric_limits<unsigned long>::digits : std::numeric_limits<unsigned long>::digits + digits);
|
|
1266
|
+
unsigned long l = static_cast<unsigned long>(mpf_get_ui(t.data()));
|
|
1267
|
+
if (digits < 0)
|
|
1268
|
+
l >>= -digits;
|
|
1269
|
+
*result |= l;
|
|
1270
|
+
}
|
|
1271
|
+
if (eval_get_sign(val) < 0)
|
|
1272
|
+
*result = -*result;
|
|
1273
|
+
}
|
|
1274
|
+
template <unsigned digits10>
|
|
1275
|
+
inline void eval_convert_to(unsigned long long* result, const gmp_float<digits10>& val)
|
|
1276
|
+
{
|
|
1277
|
+
gmp_float<digits10> t(val);
|
|
1278
|
+
|
|
1279
|
+
long digits = std::numeric_limits<long long>::digits - std::numeric_limits<long>::digits;
|
|
1280
|
+
|
|
1281
|
+
if (digits > 0)
|
|
1282
|
+
mpf_div_2exp(t.data(), t.data(), digits);
|
|
1283
|
+
|
|
1284
|
+
if (!mpf_fits_ulong_p(t.data()))
|
|
1285
|
+
{
|
|
1286
|
+
*result = (std::numeric_limits<long long>::max)();
|
|
1287
|
+
return;
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
*result = mpf_get_ui(t.data());
|
|
1291
|
+
while (digits > 0)
|
|
1292
|
+
{
|
|
1293
|
+
*result <<= digits;
|
|
1294
|
+
digits -= std::numeric_limits<unsigned long>::digits;
|
|
1295
|
+
mpf_mul_2exp(t.data(), t.data(), digits >= 0 ? std::numeric_limits<unsigned long>::digits : std::numeric_limits<unsigned long>::digits + digits);
|
|
1296
|
+
unsigned long l = static_cast<unsigned long>(mpf_get_ui(t.data()));
|
|
1297
|
+
if (digits < 0)
|
|
1298
|
+
l >>= -digits;
|
|
1299
|
+
*result |= l;
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
#endif
|
|
1303
|
+
|
|
1304
|
+
|
|
1305
|
+
#ifdef BOOST_HAS_FLOAT128
|
|
1306
|
+
template <unsigned digits10>
|
|
1307
|
+
inline void eval_convert_to(float128_type* result, const gmp_float<digits10>& val)
|
|
1308
|
+
{
|
|
1309
|
+
*result = float128_procs::strtoflt128(val.str(0, std::ios_base::scientific).c_str(), nullptr);
|
|
1310
|
+
}
|
|
1311
|
+
#endif
|
|
1312
|
+
|
|
1313
|
+
|
|
1314
|
+
//
|
|
1315
|
+
// Native non-member operations:
|
|
1316
|
+
//
|
|
1317
|
+
template <unsigned Digits10>
|
|
1318
|
+
inline void eval_sqrt(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
|
|
1319
|
+
{
|
|
1320
|
+
mpf_sqrt(result.data(), val.data());
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
template <unsigned Digits10>
|
|
1324
|
+
inline void eval_abs(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
|
|
1325
|
+
{
|
|
1326
|
+
mpf_abs(result.data(), val.data());
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
template <unsigned Digits10>
|
|
1330
|
+
inline void eval_fabs(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
|
|
1331
|
+
{
|
|
1332
|
+
mpf_abs(result.data(), val.data());
|
|
1333
|
+
}
|
|
1334
|
+
template <unsigned Digits10>
|
|
1335
|
+
inline void eval_ceil(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
|
|
1336
|
+
{
|
|
1337
|
+
mpf_ceil(result.data(), val.data());
|
|
1338
|
+
}
|
|
1339
|
+
template <unsigned Digits10>
|
|
1340
|
+
inline void eval_floor(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
|
|
1341
|
+
{
|
|
1342
|
+
mpf_floor(result.data(), val.data());
|
|
1343
|
+
}
|
|
1344
|
+
template <unsigned Digits10>
|
|
1345
|
+
inline void eval_trunc(gmp_float<Digits10>& result, const gmp_float<Digits10>& val)
|
|
1346
|
+
{
|
|
1347
|
+
mpf_trunc(result.data(), val.data());
|
|
1348
|
+
}
|
|
1349
|
+
template <unsigned Digits10>
|
|
1350
|
+
inline void eval_ldexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, long e)
|
|
1351
|
+
{
|
|
1352
|
+
if (e > 0)
|
|
1353
|
+
mpf_mul_2exp(result.data(), val.data(), static_cast<mp_bitcnt_t>(e));
|
|
1354
|
+
else if (e < 0)
|
|
1355
|
+
mpf_div_2exp(result.data(), val.data(), static_cast<mp_bitcnt_t>(-e));
|
|
1356
|
+
else
|
|
1357
|
+
result = val;
|
|
1358
|
+
}
|
|
1359
|
+
template <unsigned Digits10>
|
|
1360
|
+
inline void eval_frexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, int* e)
|
|
1361
|
+
{
|
|
1362
|
+
#if (BOOST_MP_MPIR_VERSION >= 20600) && (BOOST_MP_MPIR_VERSION < 30000)
|
|
1363
|
+
mpir_si v;
|
|
1364
|
+
mpf_get_d_2exp(&v, val.data());
|
|
1365
|
+
#else
|
|
1366
|
+
long v;
|
|
1367
|
+
mpf_get_d_2exp(&v, val.data());
|
|
1368
|
+
#endif
|
|
1369
|
+
*e = static_cast<int>(v);
|
|
1370
|
+
eval_ldexp(result, val, -v);
|
|
1371
|
+
}
|
|
1372
|
+
template <unsigned Digits10>
|
|
1373
|
+
inline void eval_frexp(gmp_float<Digits10>& result, const gmp_float<Digits10>& val, long* e)
|
|
1374
|
+
{
|
|
1375
|
+
#if (BOOST_MP_MPIR_VERSION >= 20600) && (BOOST_MP_MPIR_VERSION < 30000)
|
|
1376
|
+
mpir_si v;
|
|
1377
|
+
mpf_get_d_2exp(&v, val.data());
|
|
1378
|
+
*e = v;
|
|
1379
|
+
eval_ldexp(result, val, -v);
|
|
1380
|
+
#else
|
|
1381
|
+
mpf_get_d_2exp(e, val.data());
|
|
1382
|
+
eval_ldexp(result, val, -*e);
|
|
1383
|
+
#endif
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
template <unsigned Digits10>
|
|
1387
|
+
inline std::size_t hash_value(const gmp_float<Digits10>& val)
|
|
1388
|
+
{
|
|
1389
|
+
std::size_t result = 0;
|
|
1390
|
+
for (int i = 0; i < std::abs(val.data()[0]._mp_size); ++i)
|
|
1391
|
+
boost::multiprecision::detail::hash_combine(result, val.data()[0]._mp_d[i]);
|
|
1392
|
+
boost::multiprecision::detail::hash_combine(result, val.data()[0]._mp_exp, val.data()[0]._mp_size);
|
|
1393
|
+
return result;
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
struct gmp_int
|
|
1397
|
+
{
|
|
1398
|
+
#ifdef BOOST_HAS_LONG_LONG
|
|
1399
|
+
using signed_types = std::tuple<long, long long> ;
|
|
1400
|
+
using unsigned_types = std::tuple<unsigned long, unsigned long long>;
|
|
1401
|
+
#else
|
|
1402
|
+
using signed_types = std::tuple<long> ;
|
|
1403
|
+
using unsigned_types = std::tuple<unsigned long>;
|
|
1404
|
+
#endif
|
|
1405
|
+
using float_types = std::tuple<double, long double>;
|
|
1406
|
+
|
|
1407
|
+
gmp_int()
|
|
1408
|
+
{
|
|
1409
|
+
mpz_init(this->m_data);
|
|
1410
|
+
}
|
|
1411
|
+
gmp_int(const gmp_int& o)
|
|
1412
|
+
{
|
|
1413
|
+
if (o.m_data[0]._mp_d)
|
|
1414
|
+
mpz_init_set(m_data, o.m_data);
|
|
1415
|
+
else
|
|
1416
|
+
mpz_init(this->m_data);
|
|
1417
|
+
}
|
|
1418
|
+
// rvalue
|
|
1419
|
+
gmp_int(gmp_int&& o) noexcept
|
|
1420
|
+
{
|
|
1421
|
+
m_data[0] = o.m_data[0];
|
|
1422
|
+
o.m_data[0]._mp_d = nullptr;
|
|
1423
|
+
}
|
|
1424
|
+
explicit gmp_int(const mpf_t val)
|
|
1425
|
+
{
|
|
1426
|
+
mpz_init(this->m_data);
|
|
1427
|
+
mpz_set_f(this->m_data, val);
|
|
1428
|
+
}
|
|
1429
|
+
gmp_int(const mpz_t val)
|
|
1430
|
+
{
|
|
1431
|
+
mpz_init_set(this->m_data, val);
|
|
1432
|
+
}
|
|
1433
|
+
gmp_int(long i)
|
|
1434
|
+
{
|
|
1435
|
+
mpz_init_set_si(this->m_data, i);
|
|
1436
|
+
}
|
|
1437
|
+
gmp_int(unsigned long i)
|
|
1438
|
+
{
|
|
1439
|
+
mpz_init_set_ui(this->m_data, i);
|
|
1440
|
+
}
|
|
1441
|
+
explicit gmp_int(const mpq_t val)
|
|
1442
|
+
{
|
|
1443
|
+
mpz_init(this->m_data);
|
|
1444
|
+
mpz_set_q(this->m_data, val);
|
|
1445
|
+
}
|
|
1446
|
+
template <unsigned Digits10>
|
|
1447
|
+
explicit gmp_int(const gmp_float<Digits10>& o)
|
|
1448
|
+
{
|
|
1449
|
+
mpz_init(this->m_data);
|
|
1450
|
+
mpz_set_f(this->m_data, o.data());
|
|
1451
|
+
}
|
|
1452
|
+
explicit gmp_int(const gmp_rational& o);
|
|
1453
|
+
gmp_int& operator=(const gmp_int& o)
|
|
1454
|
+
{
|
|
1455
|
+
if (m_data[0]._mp_d == nullptr)
|
|
1456
|
+
mpz_init(this->m_data);
|
|
1457
|
+
mpz_set(m_data, o.m_data);
|
|
1458
|
+
return *this;
|
|
1459
|
+
}
|
|
1460
|
+
// rvalue copy
|
|
1461
|
+
gmp_int& operator=(gmp_int&& o) noexcept
|
|
1462
|
+
{
|
|
1463
|
+
mpz_swap(m_data, o.m_data);
|
|
1464
|
+
return *this;
|
|
1465
|
+
}
|
|
1466
|
+
#ifdef BOOST_HAS_LONG_LONG
|
|
1467
|
+
#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
|
|
1468
|
+
gmp_int& operator=(unsigned long long i)
|
|
1469
|
+
{
|
|
1470
|
+
*this = static_cast<unsigned long>(i);
|
|
1471
|
+
return *this;
|
|
1472
|
+
}
|
|
1473
|
+
#else
|
|
1474
|
+
gmp_int& operator=(unsigned long long i)
|
|
1475
|
+
{
|
|
1476
|
+
if (m_data[0]._mp_d == nullptr)
|
|
1477
|
+
mpz_init(this->m_data);
|
|
1478
|
+
unsigned long long mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
|
|
1479
|
+
unsigned shift = 0;
|
|
1480
|
+
mpz_t t;
|
|
1481
|
+
mpz_set_ui(m_data, 0);
|
|
1482
|
+
mpz_init_set_ui(t, 0);
|
|
1483
|
+
while (i)
|
|
1484
|
+
{
|
|
1485
|
+
mpz_set_ui(t, static_cast<unsigned long>(i & mask));
|
|
1486
|
+
if (shift)
|
|
1487
|
+
mpz_mul_2exp(t, t, shift);
|
|
1488
|
+
mpz_add(m_data, m_data, t);
|
|
1489
|
+
shift += std::numeric_limits<unsigned long>::digits;
|
|
1490
|
+
i >>= std::numeric_limits<unsigned long>::digits;
|
|
1491
|
+
}
|
|
1492
|
+
mpz_clear(t);
|
|
1493
|
+
return *this;
|
|
1494
|
+
}
|
|
1495
|
+
#endif
|
|
1496
|
+
gmp_int& operator=(long long i)
|
|
1497
|
+
{
|
|
1498
|
+
if (m_data[0]._mp_d == nullptr)
|
|
1499
|
+
mpz_init(this->m_data);
|
|
1500
|
+
bool neg = i < 0;
|
|
1501
|
+
*this = boost::multiprecision::detail::unsigned_abs(i);
|
|
1502
|
+
if (neg)
|
|
1503
|
+
mpz_neg(m_data, m_data);
|
|
1504
|
+
return *this;
|
|
1505
|
+
}
|
|
1506
|
+
#endif
|
|
1507
|
+
#ifdef BOOST_HAS_INT128
|
|
1508
|
+
gmp_int& operator=(uint128_type i)
|
|
1509
|
+
{
|
|
1510
|
+
if (m_data[0]._mp_d == nullptr)
|
|
1511
|
+
mpz_init(this->m_data);
|
|
1512
|
+
uint128_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
|
|
1513
|
+
unsigned shift = 0;
|
|
1514
|
+
mpz_t t;
|
|
1515
|
+
mpz_set_ui(m_data, 0);
|
|
1516
|
+
mpz_init_set_ui(t, 0);
|
|
1517
|
+
while (i)
|
|
1518
|
+
{
|
|
1519
|
+
mpz_set_ui(t, static_cast<unsigned long>(i & mask));
|
|
1520
|
+
if (shift)
|
|
1521
|
+
mpz_mul_2exp(t, t, shift);
|
|
1522
|
+
mpz_add(m_data, m_data, t);
|
|
1523
|
+
shift += std::numeric_limits<unsigned long>::digits;
|
|
1524
|
+
i >>= std::numeric_limits<unsigned long>::digits;
|
|
1525
|
+
}
|
|
1526
|
+
mpz_clear(t);
|
|
1527
|
+
return *this;
|
|
1528
|
+
}
|
|
1529
|
+
gmp_int& operator=(int128_type i)
|
|
1530
|
+
{
|
|
1531
|
+
if (m_data[0]._mp_d == nullptr)
|
|
1532
|
+
mpz_init(this->m_data);
|
|
1533
|
+
bool neg = i < 0;
|
|
1534
|
+
*this = boost::multiprecision::detail::unsigned_abs(i);
|
|
1535
|
+
if (neg)
|
|
1536
|
+
mpz_neg(m_data, m_data);
|
|
1537
|
+
return *this;
|
|
1538
|
+
}
|
|
1539
|
+
#endif
|
|
1540
|
+
gmp_int& operator=(unsigned long i)
|
|
1541
|
+
{
|
|
1542
|
+
if (m_data[0]._mp_d == nullptr)
|
|
1543
|
+
mpz_init(this->m_data);
|
|
1544
|
+
mpz_set_ui(m_data, i);
|
|
1545
|
+
return *this;
|
|
1546
|
+
}
|
|
1547
|
+
gmp_int& operator=(long i)
|
|
1548
|
+
{
|
|
1549
|
+
if (m_data[0]._mp_d == nullptr)
|
|
1550
|
+
mpz_init(this->m_data);
|
|
1551
|
+
mpz_set_si(m_data, i);
|
|
1552
|
+
return *this;
|
|
1553
|
+
}
|
|
1554
|
+
gmp_int& operator=(double d)
|
|
1555
|
+
{
|
|
1556
|
+
if (m_data[0]._mp_d == nullptr)
|
|
1557
|
+
mpz_init(this->m_data);
|
|
1558
|
+
mpz_set_d(m_data, d);
|
|
1559
|
+
return *this;
|
|
1560
|
+
}
|
|
1561
|
+
template <class F>
|
|
1562
|
+
gmp_int& assign_float(F a)
|
|
1563
|
+
{
|
|
1564
|
+
BOOST_MP_FLOAT128_USING using std::floor; using std::frexp; using std::ldexp;
|
|
1565
|
+
|
|
1566
|
+
if (m_data[0]._mp_d == nullptr)
|
|
1567
|
+
mpz_init(this->m_data);
|
|
1568
|
+
|
|
1569
|
+
if (a == 0)
|
|
1570
|
+
{
|
|
1571
|
+
mpz_set_si(m_data, 0);
|
|
1572
|
+
return *this;
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
if (a == 1)
|
|
1576
|
+
{
|
|
1577
|
+
mpz_set_si(m_data, 1);
|
|
1578
|
+
return *this;
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
BOOST_MP_ASSERT(!BOOST_MP_ISINF(a));
|
|
1582
|
+
BOOST_MP_ASSERT(!BOOST_MP_ISNAN(a));
|
|
1583
|
+
|
|
1584
|
+
int e;
|
|
1585
|
+
F f, term;
|
|
1586
|
+
mpz_set_ui(m_data, 0u);
|
|
1587
|
+
|
|
1588
|
+
f = frexp(a, &e);
|
|
1589
|
+
|
|
1590
|
+
constexpr int shift = std::numeric_limits<int>::digits - 1;
|
|
1591
|
+
|
|
1592
|
+
while (f != static_cast<F>(0.0f))
|
|
1593
|
+
{
|
|
1594
|
+
// extract int sized bits from f:
|
|
1595
|
+
f = ldexp(f, shift);
|
|
1596
|
+
term = floor(f);
|
|
1597
|
+
e -= shift;
|
|
1598
|
+
mpz_mul_2exp(m_data, m_data, shift);
|
|
1599
|
+
if (term > 0)
|
|
1600
|
+
mpz_add_ui(m_data, m_data, static_cast<unsigned>(term));
|
|
1601
|
+
else
|
|
1602
|
+
mpz_sub_ui(m_data, m_data, static_cast<unsigned>(-term));
|
|
1603
|
+
f -= term;
|
|
1604
|
+
}
|
|
1605
|
+
if (e > 0)
|
|
1606
|
+
mpz_mul_2exp(m_data, m_data, static_cast<mp_bitcnt_t>(e));
|
|
1607
|
+
else if (e < 0)
|
|
1608
|
+
mpz_div_2exp(m_data, m_data, static_cast<mp_bitcnt_t>(-e));
|
|
1609
|
+
return *this;
|
|
1610
|
+
}
|
|
1611
|
+
gmp_int& operator=(long double a)
|
|
1612
|
+
{
|
|
1613
|
+
return assign_float(a);
|
|
1614
|
+
}
|
|
1615
|
+
gmp_int& operator=(const char* s)
|
|
1616
|
+
{
|
|
1617
|
+
if (m_data[0]._mp_d == nullptr)
|
|
1618
|
+
mpz_init(this->m_data);
|
|
1619
|
+
std::size_t n = s ? std::strlen(s) : 0;
|
|
1620
|
+
int radix = 10;
|
|
1621
|
+
if (n && (*s == '0'))
|
|
1622
|
+
{
|
|
1623
|
+
if ((n > 1) && ((s[1] == 'x') || (s[1] == 'X')))
|
|
1624
|
+
{
|
|
1625
|
+
radix = 16;
|
|
1626
|
+
s += 2;
|
|
1627
|
+
n -= 2;
|
|
1628
|
+
}
|
|
1629
|
+
else
|
|
1630
|
+
{
|
|
1631
|
+
radix = 8;
|
|
1632
|
+
n -= 1;
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
if (n)
|
|
1636
|
+
{
|
|
1637
|
+
if (0 != mpz_set_str(m_data, s, radix))
|
|
1638
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid integer.")));
|
|
1639
|
+
}
|
|
1640
|
+
else
|
|
1641
|
+
mpz_set_ui(m_data, 0);
|
|
1642
|
+
return *this;
|
|
1643
|
+
}
|
|
1644
|
+
#ifdef BOOST_HAS_FLOAT128
|
|
1645
|
+
gmp_int& operator=(float128_type a)
|
|
1646
|
+
{
|
|
1647
|
+
return assign_float(a);
|
|
1648
|
+
}
|
|
1649
|
+
#endif
|
|
1650
|
+
gmp_int& operator=(const mpf_t val)
|
|
1651
|
+
{
|
|
1652
|
+
if (m_data[0]._mp_d == nullptr)
|
|
1653
|
+
mpz_init(this->m_data);
|
|
1654
|
+
mpz_set_f(this->m_data, val);
|
|
1655
|
+
return *this;
|
|
1656
|
+
}
|
|
1657
|
+
gmp_int& operator=(const mpz_t val)
|
|
1658
|
+
{
|
|
1659
|
+
if (m_data[0]._mp_d == nullptr)
|
|
1660
|
+
mpz_init(this->m_data);
|
|
1661
|
+
mpz_set(this->m_data, val);
|
|
1662
|
+
return *this;
|
|
1663
|
+
}
|
|
1664
|
+
gmp_int& operator=(const mpq_t val)
|
|
1665
|
+
{
|
|
1666
|
+
if (m_data[0]._mp_d == nullptr)
|
|
1667
|
+
mpz_init(this->m_data);
|
|
1668
|
+
mpz_set_q(this->m_data, val);
|
|
1669
|
+
return *this;
|
|
1670
|
+
}
|
|
1671
|
+
template <unsigned Digits10>
|
|
1672
|
+
gmp_int& operator=(const gmp_float<Digits10>& o)
|
|
1673
|
+
{
|
|
1674
|
+
if (m_data[0]._mp_d == nullptr)
|
|
1675
|
+
mpz_init(this->m_data);
|
|
1676
|
+
mpz_set_f(this->m_data, o.data());
|
|
1677
|
+
return *this;
|
|
1678
|
+
}
|
|
1679
|
+
gmp_int& operator=(const gmp_rational& o);
|
|
1680
|
+
void swap(gmp_int& o)
|
|
1681
|
+
{
|
|
1682
|
+
mpz_swap(m_data, o.m_data);
|
|
1683
|
+
}
|
|
1684
|
+
std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags f) const
|
|
1685
|
+
{
|
|
1686
|
+
BOOST_MP_ASSERT(m_data[0]._mp_d);
|
|
1687
|
+
|
|
1688
|
+
int base = 10;
|
|
1689
|
+
if ((f & std::ios_base::oct) == std::ios_base::oct)
|
|
1690
|
+
base = 8;
|
|
1691
|
+
else if ((f & std::ios_base::hex) == std::ios_base::hex)
|
|
1692
|
+
base = 16;
|
|
1693
|
+
//
|
|
1694
|
+
// sanity check, bases 8 and 16 are only available for positive numbers:
|
|
1695
|
+
//
|
|
1696
|
+
if ((base != 10) && (mpz_sgn(m_data) < 0))
|
|
1697
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Formatted output in bases 8 or 16 is only available for positive numbers"));
|
|
1698
|
+
void* (*alloc_func_ptr)(size_t);
|
|
1699
|
+
void* (*realloc_func_ptr)(void*, size_t, size_t);
|
|
1700
|
+
void (*free_func_ptr)(void*, size_t);
|
|
1701
|
+
const char* ps = mpz_get_str(nullptr, base, m_data);
|
|
1702
|
+
std::string s = ps;
|
|
1703
|
+
mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
|
|
1704
|
+
(*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
|
|
1705
|
+
if (f & std::ios_base::uppercase)
|
|
1706
|
+
for (size_t i = 0; i < s.length(); ++i)
|
|
1707
|
+
s[i] = static_cast<char>(std::toupper(s[i]));
|
|
1708
|
+
if ((base != 10) && (f & std::ios_base::showbase))
|
|
1709
|
+
{
|
|
1710
|
+
int pos = s[0] == '-' ? 1 : 0;
|
|
1711
|
+
const char* pp = base == 8 ? "0" : (f & std::ios_base::uppercase) ? "0X" : "0x";
|
|
1712
|
+
s.insert(static_cast<std::string::size_type>(pos), pp);
|
|
1713
|
+
}
|
|
1714
|
+
if ((f & std::ios_base::showpos) && (s[0] != '-'))
|
|
1715
|
+
s.insert(static_cast<std::string::size_type>(0), 1, '+');
|
|
1716
|
+
|
|
1717
|
+
return s;
|
|
1718
|
+
}
|
|
1719
|
+
~gmp_int() noexcept
|
|
1720
|
+
{
|
|
1721
|
+
if (m_data[0]._mp_d)
|
|
1722
|
+
mpz_clear(m_data);
|
|
1723
|
+
}
|
|
1724
|
+
void negate() noexcept
|
|
1725
|
+
{
|
|
1726
|
+
BOOST_MP_ASSERT(m_data[0]._mp_d);
|
|
1727
|
+
mpz_neg(m_data, m_data);
|
|
1728
|
+
}
|
|
1729
|
+
int compare(const gmp_int& o) const noexcept
|
|
1730
|
+
{
|
|
1731
|
+
BOOST_MP_ASSERT(m_data[0]._mp_d && o.m_data[0]._mp_d);
|
|
1732
|
+
return mpz_cmp(m_data, o.m_data);
|
|
1733
|
+
}
|
|
1734
|
+
int compare(long i) const noexcept
|
|
1735
|
+
{
|
|
1736
|
+
BOOST_MP_ASSERT(m_data[0]._mp_d);
|
|
1737
|
+
return mpz_cmp_si(m_data, i);
|
|
1738
|
+
}
|
|
1739
|
+
int compare(unsigned long i) const noexcept
|
|
1740
|
+
{
|
|
1741
|
+
BOOST_MP_ASSERT(m_data[0]._mp_d);
|
|
1742
|
+
return mpz_cmp_ui(m_data, i);
|
|
1743
|
+
}
|
|
1744
|
+
template <class V>
|
|
1745
|
+
int compare(V v) const
|
|
1746
|
+
{
|
|
1747
|
+
gmp_int d;
|
|
1748
|
+
d = v;
|
|
1749
|
+
return compare(d);
|
|
1750
|
+
}
|
|
1751
|
+
mpz_t& data() noexcept
|
|
1752
|
+
{
|
|
1753
|
+
BOOST_MP_ASSERT(m_data[0]._mp_d);
|
|
1754
|
+
return m_data;
|
|
1755
|
+
}
|
|
1756
|
+
const mpz_t& data() const noexcept
|
|
1757
|
+
{
|
|
1758
|
+
BOOST_MP_ASSERT(m_data[0]._mp_d);
|
|
1759
|
+
return m_data;
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
protected:
|
|
1763
|
+
mpz_t m_data;
|
|
1764
|
+
};
|
|
1765
|
+
|
|
1766
|
+
template <class T>
|
|
1767
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_eq(const gmp_int& a, const T& b)
|
|
1768
|
+
{
|
|
1769
|
+
return a.compare(b) == 0;
|
|
1770
|
+
}
|
|
1771
|
+
template <class T>
|
|
1772
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_lt(const gmp_int& a, const T& b)
|
|
1773
|
+
{
|
|
1774
|
+
return a.compare(b) < 0;
|
|
1775
|
+
}
|
|
1776
|
+
template <class T>
|
|
1777
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value, bool>::type eval_gt(const gmp_int& a, const T& b)
|
|
1778
|
+
{
|
|
1779
|
+
return a.compare(b) > 0;
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
inline bool eval_is_zero(const gmp_int& val)
|
|
1783
|
+
{
|
|
1784
|
+
return mpz_sgn(val.data()) == 0;
|
|
1785
|
+
}
|
|
1786
|
+
inline void eval_add(gmp_int& t, const gmp_int& o)
|
|
1787
|
+
{
|
|
1788
|
+
mpz_add(t.data(), t.data(), o.data());
|
|
1789
|
+
}
|
|
1790
|
+
inline void eval_multiply_add(gmp_int& t, const gmp_int& a, const gmp_int& b)
|
|
1791
|
+
{
|
|
1792
|
+
mpz_addmul(t.data(), a.data(), b.data());
|
|
1793
|
+
}
|
|
1794
|
+
inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, const gmp_int& b)
|
|
1795
|
+
{
|
|
1796
|
+
mpz_submul(t.data(), a.data(), b.data());
|
|
1797
|
+
}
|
|
1798
|
+
inline void eval_subtract(gmp_int& t, const gmp_int& o)
|
|
1799
|
+
{
|
|
1800
|
+
mpz_sub(t.data(), t.data(), o.data());
|
|
1801
|
+
}
|
|
1802
|
+
inline void eval_multiply(gmp_int& t, const gmp_int& o)
|
|
1803
|
+
{
|
|
1804
|
+
mpz_mul(t.data(), t.data(), o.data());
|
|
1805
|
+
}
|
|
1806
|
+
inline void eval_divide(gmp_int& t, const gmp_int& o)
|
|
1807
|
+
{
|
|
1808
|
+
if (eval_is_zero(o))
|
|
1809
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
1810
|
+
mpz_tdiv_q(t.data(), t.data(), o.data());
|
|
1811
|
+
}
|
|
1812
|
+
inline void eval_modulus(gmp_int& t, const gmp_int& o)
|
|
1813
|
+
{
|
|
1814
|
+
mpz_tdiv_r(t.data(), t.data(), o.data());
|
|
1815
|
+
}
|
|
1816
|
+
inline void eval_add(gmp_int& t, unsigned long i)
|
|
1817
|
+
{
|
|
1818
|
+
mpz_add_ui(t.data(), t.data(), i);
|
|
1819
|
+
}
|
|
1820
|
+
inline void eval_multiply_add(gmp_int& t, const gmp_int& a, unsigned long i)
|
|
1821
|
+
{
|
|
1822
|
+
mpz_addmul_ui(t.data(), a.data(), i);
|
|
1823
|
+
}
|
|
1824
|
+
inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, unsigned long i)
|
|
1825
|
+
{
|
|
1826
|
+
mpz_submul_ui(t.data(), a.data(), i);
|
|
1827
|
+
}
|
|
1828
|
+
inline void eval_subtract(gmp_int& t, unsigned long i)
|
|
1829
|
+
{
|
|
1830
|
+
mpz_sub_ui(t.data(), t.data(), i);
|
|
1831
|
+
}
|
|
1832
|
+
inline void eval_multiply(gmp_int& t, unsigned long i)
|
|
1833
|
+
{
|
|
1834
|
+
mpz_mul_ui(t.data(), t.data(), i);
|
|
1835
|
+
}
|
|
1836
|
+
inline void eval_modulus(gmp_int& t, unsigned long i)
|
|
1837
|
+
{
|
|
1838
|
+
mpz_tdiv_r_ui(t.data(), t.data(), i);
|
|
1839
|
+
}
|
|
1840
|
+
inline void eval_divide(gmp_int& t, unsigned long i)
|
|
1841
|
+
{
|
|
1842
|
+
if (i == 0)
|
|
1843
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
1844
|
+
mpz_tdiv_q_ui(t.data(), t.data(), i);
|
|
1845
|
+
}
|
|
1846
|
+
inline void eval_add(gmp_int& t, long i)
|
|
1847
|
+
{
|
|
1848
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
1849
|
+
|
|
1850
|
+
if (i > 0)
|
|
1851
|
+
mpz_add_ui(t.data(), t.data(), static_cast<local_uint_type>(i));
|
|
1852
|
+
else if (i < 0)
|
|
1853
|
+
mpz_sub_ui(t.data(), t.data(), static_cast<local_uint_type>(-i));
|
|
1854
|
+
}
|
|
1855
|
+
inline void eval_multiply_add(gmp_int& t, const gmp_int& a, long i)
|
|
1856
|
+
{
|
|
1857
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
1858
|
+
|
|
1859
|
+
if (i > 0)
|
|
1860
|
+
mpz_addmul_ui(t.data(), a.data(), static_cast<local_uint_type>(i));
|
|
1861
|
+
else
|
|
1862
|
+
mpz_submul_ui(t.data(), a.data(), static_cast<local_uint_type>(-i));
|
|
1863
|
+
}
|
|
1864
|
+
inline void eval_multiply_subtract(gmp_int& t, const gmp_int& a, long i)
|
|
1865
|
+
{
|
|
1866
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
1867
|
+
|
|
1868
|
+
if (i > 0)
|
|
1869
|
+
mpz_submul_ui(t.data(), a.data(), static_cast<local_uint_type>(i));
|
|
1870
|
+
else
|
|
1871
|
+
mpz_addmul_ui(t.data(), a.data(), static_cast<local_uint_type>(-i));
|
|
1872
|
+
}
|
|
1873
|
+
inline void eval_subtract(gmp_int& t, long i)
|
|
1874
|
+
{
|
|
1875
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
1876
|
+
|
|
1877
|
+
if (i > 0)
|
|
1878
|
+
mpz_sub_ui(t.data(), t.data(), static_cast<local_uint_type>(i));
|
|
1879
|
+
else if (i < 0)
|
|
1880
|
+
mpz_add_ui(t.data(), t.data(), static_cast<local_uint_type>(-i));
|
|
1881
|
+
}
|
|
1882
|
+
inline void eval_multiply(gmp_int& t, long i)
|
|
1883
|
+
{
|
|
1884
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
1885
|
+
|
|
1886
|
+
mpz_mul_ui(t.data(), t.data(), static_cast<local_uint_type>(boost::multiprecision::detail::unsigned_abs(i)));
|
|
1887
|
+
|
|
1888
|
+
if (i < 0)
|
|
1889
|
+
mpz_neg(t.data(), t.data());
|
|
1890
|
+
}
|
|
1891
|
+
inline void eval_modulus(gmp_int& t, long i)
|
|
1892
|
+
{
|
|
1893
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
1894
|
+
|
|
1895
|
+
mpz_tdiv_r_ui(t.data(), t.data(), static_cast<local_uint_type>(boost::multiprecision::detail::unsigned_abs(i)));
|
|
1896
|
+
}
|
|
1897
|
+
inline void eval_divide(gmp_int& t, long i)
|
|
1898
|
+
{
|
|
1899
|
+
if (i == 0)
|
|
1900
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
1901
|
+
|
|
1902
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
1903
|
+
|
|
1904
|
+
mpz_tdiv_q_ui(t.data(), t.data(), static_cast<local_uint_type>(boost::multiprecision::detail::unsigned_abs(i)));
|
|
1905
|
+
|
|
1906
|
+
if (i < 0)
|
|
1907
|
+
mpz_neg(t.data(), t.data());
|
|
1908
|
+
}
|
|
1909
|
+
template <class UI>
|
|
1910
|
+
inline void eval_left_shift(gmp_int& t, UI i)
|
|
1911
|
+
{
|
|
1912
|
+
mpz_mul_2exp(t.data(), t.data(), static_cast<unsigned long>(i));
|
|
1913
|
+
}
|
|
1914
|
+
template <class UI>
|
|
1915
|
+
inline void eval_right_shift(gmp_int& t, UI i)
|
|
1916
|
+
{
|
|
1917
|
+
mpz_fdiv_q_2exp(t.data(), t.data(), static_cast<unsigned long>(i));
|
|
1918
|
+
}
|
|
1919
|
+
template <class UI>
|
|
1920
|
+
inline void eval_left_shift(gmp_int& t, const gmp_int& v, UI i)
|
|
1921
|
+
{
|
|
1922
|
+
mpz_mul_2exp(t.data(), v.data(), static_cast<unsigned long>(i));
|
|
1923
|
+
}
|
|
1924
|
+
template <class UI>
|
|
1925
|
+
inline void eval_right_shift(gmp_int& t, const gmp_int& v, UI i)
|
|
1926
|
+
{
|
|
1927
|
+
mpz_fdiv_q_2exp(t.data(), v.data(), static_cast<unsigned long>(i));
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1930
|
+
inline void eval_bitwise_and(gmp_int& result, const gmp_int& v)
|
|
1931
|
+
{
|
|
1932
|
+
mpz_and(result.data(), result.data(), v.data());
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
inline void eval_bitwise_or(gmp_int& result, const gmp_int& v)
|
|
1936
|
+
{
|
|
1937
|
+
mpz_ior(result.data(), result.data(), v.data());
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
inline void eval_bitwise_xor(gmp_int& result, const gmp_int& v)
|
|
1941
|
+
{
|
|
1942
|
+
mpz_xor(result.data(), result.data(), v.data());
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1945
|
+
inline void eval_add(gmp_int& t, const gmp_int& p, const gmp_int& o)
|
|
1946
|
+
{
|
|
1947
|
+
mpz_add(t.data(), p.data(), o.data());
|
|
1948
|
+
}
|
|
1949
|
+
inline void eval_subtract(gmp_int& t, const gmp_int& p, const gmp_int& o)
|
|
1950
|
+
{
|
|
1951
|
+
mpz_sub(t.data(), p.data(), o.data());
|
|
1952
|
+
}
|
|
1953
|
+
inline void eval_multiply(gmp_int& t, const gmp_int& p, const gmp_int& o)
|
|
1954
|
+
{
|
|
1955
|
+
mpz_mul(t.data(), p.data(), o.data());
|
|
1956
|
+
}
|
|
1957
|
+
inline void eval_divide(gmp_int& t, const gmp_int& p, const gmp_int& o)
|
|
1958
|
+
{
|
|
1959
|
+
if (eval_is_zero(o))
|
|
1960
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
1961
|
+
mpz_tdiv_q(t.data(), p.data(), o.data());
|
|
1962
|
+
}
|
|
1963
|
+
inline void eval_modulus(gmp_int& t, const gmp_int& p, const gmp_int& o)
|
|
1964
|
+
{
|
|
1965
|
+
mpz_tdiv_r(t.data(), p.data(), o.data());
|
|
1966
|
+
}
|
|
1967
|
+
inline void eval_add(gmp_int& t, const gmp_int& p, unsigned long i)
|
|
1968
|
+
{
|
|
1969
|
+
mpz_add_ui(t.data(), p.data(), i);
|
|
1970
|
+
}
|
|
1971
|
+
inline void eval_subtract(gmp_int& t, const gmp_int& p, unsigned long i)
|
|
1972
|
+
{
|
|
1973
|
+
mpz_sub_ui(t.data(), p.data(), i);
|
|
1974
|
+
}
|
|
1975
|
+
inline void eval_multiply(gmp_int& t, const gmp_int& p, unsigned long i)
|
|
1976
|
+
{
|
|
1977
|
+
mpz_mul_ui(t.data(), p.data(), i);
|
|
1978
|
+
}
|
|
1979
|
+
inline void eval_modulus(gmp_int& t, const gmp_int& p, unsigned long i)
|
|
1980
|
+
{
|
|
1981
|
+
mpz_tdiv_r_ui(t.data(), p.data(), i);
|
|
1982
|
+
}
|
|
1983
|
+
inline void eval_divide(gmp_int& t, const gmp_int& p, unsigned long i)
|
|
1984
|
+
{
|
|
1985
|
+
if (i == 0)
|
|
1986
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
1987
|
+
mpz_tdiv_q_ui(t.data(), p.data(), i);
|
|
1988
|
+
}
|
|
1989
|
+
inline void eval_add(gmp_int& t, const gmp_int& p, long i)
|
|
1990
|
+
{
|
|
1991
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
1992
|
+
|
|
1993
|
+
if (i > 0)
|
|
1994
|
+
mpz_add_ui(t.data(), p.data(), static_cast<local_uint_type>(i));
|
|
1995
|
+
else
|
|
1996
|
+
mpz_sub_ui(t.data(), p.data(), static_cast<local_uint_type>(-i));
|
|
1997
|
+
}
|
|
1998
|
+
inline void eval_subtract(gmp_int& t, const gmp_int& p, long i)
|
|
1999
|
+
{
|
|
2000
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
2001
|
+
|
|
2002
|
+
if (i > 0)
|
|
2003
|
+
mpz_sub_ui(t.data(), p.data(), static_cast<local_uint_type>(i));
|
|
2004
|
+
else
|
|
2005
|
+
mpz_add_ui(t.data(), p.data(), static_cast<local_uint_type>(-i));
|
|
2006
|
+
}
|
|
2007
|
+
inline void eval_multiply(gmp_int& t, const gmp_int& p, long i)
|
|
2008
|
+
{
|
|
2009
|
+
mpz_mul_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
|
|
2010
|
+
if (i < 0)
|
|
2011
|
+
mpz_neg(t.data(), t.data());
|
|
2012
|
+
}
|
|
2013
|
+
inline void eval_modulus(gmp_int& t, const gmp_int& p, long i)
|
|
2014
|
+
{
|
|
2015
|
+
mpz_tdiv_r_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
|
|
2016
|
+
}
|
|
2017
|
+
inline void eval_divide(gmp_int& t, const gmp_int& p, long i)
|
|
2018
|
+
{
|
|
2019
|
+
if (i == 0)
|
|
2020
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
2021
|
+
mpz_tdiv_q_ui(t.data(), p.data(), boost::multiprecision::detail::unsigned_abs(i));
|
|
2022
|
+
if (i < 0)
|
|
2023
|
+
mpz_neg(t.data(), t.data());
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
inline void eval_bitwise_and(gmp_int& result, const gmp_int& u, const gmp_int& v)
|
|
2027
|
+
{
|
|
2028
|
+
mpz_and(result.data(), u.data(), v.data());
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
inline void eval_bitwise_or(gmp_int& result, const gmp_int& u, const gmp_int& v)
|
|
2032
|
+
{
|
|
2033
|
+
mpz_ior(result.data(), u.data(), v.data());
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
inline void eval_bitwise_xor(gmp_int& result, const gmp_int& u, const gmp_int& v)
|
|
2037
|
+
{
|
|
2038
|
+
mpz_xor(result.data(), u.data(), v.data());
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
inline void eval_complement(gmp_int& result, const gmp_int& u)
|
|
2042
|
+
{
|
|
2043
|
+
mpz_com(result.data(), u.data());
|
|
2044
|
+
}
|
|
2045
|
+
|
|
2046
|
+
inline int eval_get_sign(const gmp_int& val)
|
|
2047
|
+
{
|
|
2048
|
+
return mpz_sgn(val.data());
|
|
2049
|
+
}
|
|
2050
|
+
inline void eval_convert_to(unsigned long* result, const gmp_int& val)
|
|
2051
|
+
{
|
|
2052
|
+
if (mpz_sgn(val.data()) < 0)
|
|
2053
|
+
{
|
|
2054
|
+
BOOST_MP_THROW_EXCEPTION(std::range_error("Conversion from negative integer to an unsigned type results in undefined behaviour"));
|
|
2055
|
+
}
|
|
2056
|
+
else
|
|
2057
|
+
*result = static_cast<unsigned long>(mpz_get_ui(val.data()));
|
|
2058
|
+
}
|
|
2059
|
+
inline void eval_convert_to(long* result, const gmp_int& val)
|
|
2060
|
+
{
|
|
2061
|
+
if (0 == mpz_fits_slong_p(val.data()))
|
|
2062
|
+
{
|
|
2063
|
+
*result = mpz_sgn(val.data()) < 0 ? (std::numeric_limits<long>::min)() : (std::numeric_limits<long>::max)();
|
|
2064
|
+
}
|
|
2065
|
+
else
|
|
2066
|
+
*result = static_cast<long>(mpz_get_si(val.data()));
|
|
2067
|
+
}
|
|
2068
|
+
inline void eval_convert_to(long double* result, const gmp_int& val)
|
|
2069
|
+
{
|
|
2070
|
+
detail::gmp_char_ptr val_char_ptr {mpz_get_str(nullptr, 10, val.data())};
|
|
2071
|
+
*result = std::strtold(val_char_ptr.get(), nullptr);
|
|
2072
|
+
}
|
|
2073
|
+
inline void eval_convert_to(double* result, const gmp_int& val)
|
|
2074
|
+
{
|
|
2075
|
+
*result = mpz_get_d(val.data());
|
|
2076
|
+
}
|
|
2077
|
+
#ifdef BOOST_HAS_LONG_LONG
|
|
2078
|
+
inline void eval_convert_to(unsigned long long* result, const gmp_int& val)
|
|
2079
|
+
{
|
|
2080
|
+
if (mpz_sgn(val.data()) < 0)
|
|
2081
|
+
{
|
|
2082
|
+
BOOST_MP_THROW_EXCEPTION(std::range_error("Conversion from negative integer to an unsigned type results in undefined behaviour"));
|
|
2083
|
+
}
|
|
2084
|
+
*result = 0;
|
|
2085
|
+
gmp_int t(val);
|
|
2086
|
+
unsigned parts = sizeof(unsigned long long) / sizeof(unsigned long);
|
|
2087
|
+
|
|
2088
|
+
for (unsigned i = 0; i < parts; ++i)
|
|
2089
|
+
{
|
|
2090
|
+
unsigned long long part = mpz_get_ui(t.data());
|
|
2091
|
+
if (i)
|
|
2092
|
+
*result |= part << (i * sizeof(unsigned long) * CHAR_BIT);
|
|
2093
|
+
else
|
|
2094
|
+
*result = part;
|
|
2095
|
+
mpz_tdiv_q_2exp(t.data(), t.data(), sizeof(unsigned long) * CHAR_BIT);
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
inline void eval_convert_to(long long* result, const gmp_int& val)
|
|
2099
|
+
{
|
|
2100
|
+
int s = mpz_sgn(val.data());
|
|
2101
|
+
*result = 0;
|
|
2102
|
+
gmp_int t(val);
|
|
2103
|
+
unsigned parts = sizeof(unsigned long long) / sizeof(unsigned long);
|
|
2104
|
+
unsigned long long unsigned_result = 0;
|
|
2105
|
+
|
|
2106
|
+
for (unsigned i = 0; i < parts; ++i)
|
|
2107
|
+
{
|
|
2108
|
+
unsigned long long part = mpz_get_ui(t.data());
|
|
2109
|
+
if (i)
|
|
2110
|
+
unsigned_result |= part << (i * sizeof(unsigned long) * CHAR_BIT);
|
|
2111
|
+
else
|
|
2112
|
+
unsigned_result = part;
|
|
2113
|
+
mpz_tdiv_q_2exp(t.data(), t.data(), sizeof(unsigned long) * CHAR_BIT);
|
|
2114
|
+
}
|
|
2115
|
+
//
|
|
2116
|
+
// Overflow check:
|
|
2117
|
+
//
|
|
2118
|
+
bool overflow = false;
|
|
2119
|
+
if (mpz_sgn(t.data()))
|
|
2120
|
+
{
|
|
2121
|
+
overflow = true;
|
|
2122
|
+
}
|
|
2123
|
+
if ((s > 0) && (unsigned_result > static_cast<unsigned long long>((std::numeric_limits<long long>::max)())))
|
|
2124
|
+
overflow = true;
|
|
2125
|
+
if((s < 0) && (unsigned_result > 1u - static_cast<unsigned long long>((std::numeric_limits<long long>::min)() + 1)))
|
|
2126
|
+
overflow = true;
|
|
2127
|
+
if(overflow)
|
|
2128
|
+
*result = s < 0 ? (std::numeric_limits<long long>::min)() : (std::numeric_limits<long long>::max)();
|
|
2129
|
+
else
|
|
2130
|
+
*result = s < 0 ? -static_cast<long long>(unsigned_result - 1u) - 1 : static_cast<long long>(unsigned_result);
|
|
2131
|
+
}
|
|
2132
|
+
#endif
|
|
2133
|
+
#ifdef BOOST_HAS_INT128
|
|
2134
|
+
inline void eval_convert_to(uint128_type* result, const gmp_int& val)
|
|
2135
|
+
{
|
|
2136
|
+
if (mpz_sgn(val.data()) < 0)
|
|
2137
|
+
{
|
|
2138
|
+
BOOST_MP_THROW_EXCEPTION(std::range_error("Conversion from negative integer to an unsigned type results in undefined behaviour"));
|
|
2139
|
+
}
|
|
2140
|
+
*result = 0;
|
|
2141
|
+
gmp_int t(val);
|
|
2142
|
+
unsigned parts = sizeof(uint128_type) / sizeof(unsigned long);
|
|
2143
|
+
|
|
2144
|
+
for (unsigned i = 0; i < parts; ++i)
|
|
2145
|
+
{
|
|
2146
|
+
uint128_type part = mpz_get_ui(t.data());
|
|
2147
|
+
if (i)
|
|
2148
|
+
*result |= part << (i * sizeof(unsigned long) * CHAR_BIT);
|
|
2149
|
+
else
|
|
2150
|
+
*result = part;
|
|
2151
|
+
mpz_tdiv_q_2exp(t.data(), t.data(), sizeof(unsigned long) * CHAR_BIT);
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
inline void eval_convert_to(int128_type* result, const gmp_int& val)
|
|
2155
|
+
{
|
|
2156
|
+
int s = mpz_sgn(val.data());
|
|
2157
|
+
*result = 0;
|
|
2158
|
+
gmp_int t(val);
|
|
2159
|
+
unsigned parts = sizeof(uint128_type) / sizeof(unsigned long);
|
|
2160
|
+
uint128_type unsigned_result = 0;
|
|
2161
|
+
|
|
2162
|
+
for (unsigned i = 0; i < parts; ++i)
|
|
2163
|
+
{
|
|
2164
|
+
uint128_type part = mpz_get_ui(t.data());
|
|
2165
|
+
if (i)
|
|
2166
|
+
unsigned_result |= part << (i * sizeof(unsigned long) * CHAR_BIT);
|
|
2167
|
+
else
|
|
2168
|
+
unsigned_result = part;
|
|
2169
|
+
mpz_tdiv_q_2exp(t.data(), t.data(), sizeof(unsigned long) * CHAR_BIT);
|
|
2170
|
+
}
|
|
2171
|
+
//
|
|
2172
|
+
// Overflow check:
|
|
2173
|
+
//
|
|
2174
|
+
constexpr int128_type int128_max = static_cast<int128_type>((static_cast<uint128_type>(1u) << 127) - 1);
|
|
2175
|
+
constexpr int128_type int128_min = static_cast<int128_type>(static_cast<int128_type>(-int128_max) -1);
|
|
2176
|
+
bool overflow = false;
|
|
2177
|
+
if (mpz_sgn(t.data()))
|
|
2178
|
+
{
|
|
2179
|
+
overflow = true;
|
|
2180
|
+
}
|
|
2181
|
+
if ((s > 0) && (unsigned_result > static_cast<uint128_type>(int128_max)))
|
|
2182
|
+
overflow = true;
|
|
2183
|
+
if ((s < 0) && (unsigned_result > 1u - static_cast<uint128_type>(int128_min + 1)))
|
|
2184
|
+
overflow = true;
|
|
2185
|
+
if (overflow)
|
|
2186
|
+
*result = s < 0 ? int128_min : int128_max;
|
|
2187
|
+
else
|
|
2188
|
+
*result = s < 0 ? -static_cast<int128_type>(unsigned_result - 1u) - 1 : static_cast<int128_type>(unsigned_result);
|
|
2189
|
+
}
|
|
2190
|
+
|
|
2191
|
+
template <unsigned digits10>
|
|
2192
|
+
inline void eval_convert_to(int128_type* result, const gmp_float<digits10>& val)
|
|
2193
|
+
{
|
|
2194
|
+
gmp_int i;
|
|
2195
|
+
mpz_set_f(i.data(), val.data());
|
|
2196
|
+
eval_convert_to(result, i);
|
|
2197
|
+
}
|
|
2198
|
+
template <unsigned digits10>
|
|
2199
|
+
inline void eval_convert_to(uint128_type* result, const gmp_float<digits10>& val)
|
|
2200
|
+
{
|
|
2201
|
+
gmp_int i;
|
|
2202
|
+
mpz_set_f(i.data(), val.data());
|
|
2203
|
+
eval_convert_to(result, i);
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
#endif
|
|
2207
|
+
|
|
2208
|
+
#ifdef BOOST_HAS_FLOAT128
|
|
2209
|
+
inline void eval_convert_to(float128_type* result, const gmp_int& val)
|
|
2210
|
+
{
|
|
2211
|
+
*result = float128_procs::strtoflt128(val.str(0, std::ios_base::fixed).c_str(), nullptr);
|
|
2212
|
+
}
|
|
2213
|
+
#endif
|
|
2214
|
+
|
|
2215
|
+
inline void eval_abs(gmp_int& result, const gmp_int& val)
|
|
2216
|
+
{
|
|
2217
|
+
mpz_abs(result.data(), val.data());
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
inline void eval_gcd(gmp_int& result, const gmp_int& a, const gmp_int& b)
|
|
2221
|
+
{
|
|
2222
|
+
mpz_gcd(result.data(), a.data(), b.data());
|
|
2223
|
+
}
|
|
2224
|
+
inline void eval_lcm(gmp_int& result, const gmp_int& a, const gmp_int& b)
|
|
2225
|
+
{
|
|
2226
|
+
mpz_lcm(result.data(), a.data(), b.data());
|
|
2227
|
+
}
|
|
2228
|
+
template <class I>
|
|
2229
|
+
inline typename std::enable_if<(boost::multiprecision::detail::is_unsigned<I>::value && (sizeof(I) <= sizeof(unsigned long)))>::type eval_gcd(gmp_int& result, const gmp_int& a, const I b)
|
|
2230
|
+
{
|
|
2231
|
+
mpz_gcd_ui(result.data(), a.data(), b);
|
|
2232
|
+
}
|
|
2233
|
+
template <class I>
|
|
2234
|
+
inline typename std::enable_if<(boost::multiprecision::detail::is_unsigned<I>::value && (sizeof(I) <= sizeof(unsigned long)))>::type eval_lcm(gmp_int& result, const gmp_int& a, const I b)
|
|
2235
|
+
{
|
|
2236
|
+
mpz_lcm_ui(result.data(), a.data(), b);
|
|
2237
|
+
}
|
|
2238
|
+
template <class I>
|
|
2239
|
+
inline typename std::enable_if<(boost::multiprecision::detail::is_signed<I>::value && boost::multiprecision::detail::is_integral<I>::value && (sizeof(I) <= sizeof(long)))>::type eval_gcd(gmp_int& result, const gmp_int& a, const I b)
|
|
2240
|
+
{
|
|
2241
|
+
mpz_gcd_ui(result.data(), a.data(), boost::multiprecision::detail::unsigned_abs(b));
|
|
2242
|
+
}
|
|
2243
|
+
template <class I>
|
|
2244
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_signed<I>::value && boost::multiprecision::detail::is_integral<I>::value && ((sizeof(I) <= sizeof(long)))>::type eval_lcm(gmp_int& result, const gmp_int& a, const I b)
|
|
2245
|
+
{
|
|
2246
|
+
mpz_lcm_ui(result.data(), a.data(), boost::multiprecision::detail::unsigned_abs(b));
|
|
2247
|
+
}
|
|
2248
|
+
|
|
2249
|
+
inline void eval_integer_sqrt(gmp_int& s, gmp_int& r, const gmp_int& x)
|
|
2250
|
+
{
|
|
2251
|
+
mpz_sqrtrem(s.data(), r.data(), x.data());
|
|
2252
|
+
}
|
|
2253
|
+
|
|
2254
|
+
inline std::size_t eval_lsb(const gmp_int& val)
|
|
2255
|
+
{
|
|
2256
|
+
int c = eval_get_sign(val);
|
|
2257
|
+
if (c == 0)
|
|
2258
|
+
{
|
|
2259
|
+
BOOST_MP_THROW_EXCEPTION(std::domain_error("No bits were set in the operand."));
|
|
2260
|
+
}
|
|
2261
|
+
if (c < 0)
|
|
2262
|
+
{
|
|
2263
|
+
BOOST_MP_THROW_EXCEPTION(std::domain_error("Testing individual bits in negative values is not supported - results are undefined."));
|
|
2264
|
+
}
|
|
2265
|
+
return static_cast<unsigned>(mpz_scan1(val.data(), 0));
|
|
2266
|
+
}
|
|
2267
|
+
|
|
2268
|
+
inline std::size_t eval_msb(const gmp_int& val)
|
|
2269
|
+
{
|
|
2270
|
+
int c = eval_get_sign(val);
|
|
2271
|
+
if (c == 0)
|
|
2272
|
+
{
|
|
2273
|
+
BOOST_MP_THROW_EXCEPTION(std::domain_error("No bits were set in the operand."));
|
|
2274
|
+
}
|
|
2275
|
+
if (c < 0)
|
|
2276
|
+
{
|
|
2277
|
+
BOOST_MP_THROW_EXCEPTION(std::domain_error("Testing individual bits in negative values is not supported - results are undefined."));
|
|
2278
|
+
}
|
|
2279
|
+
return static_cast<unsigned>(mpz_sizeinbase(val.data(), 2) - 1);
|
|
2280
|
+
}
|
|
2281
|
+
|
|
2282
|
+
inline bool eval_bit_test(const gmp_int& val, std::size_t index)
|
|
2283
|
+
{
|
|
2284
|
+
return mpz_tstbit(val.data(), index) ? true : false;
|
|
2285
|
+
}
|
|
2286
|
+
|
|
2287
|
+
inline void eval_bit_set(gmp_int& val, std::size_t index)
|
|
2288
|
+
{
|
|
2289
|
+
mpz_setbit(val.data(), index);
|
|
2290
|
+
}
|
|
2291
|
+
|
|
2292
|
+
inline void eval_bit_unset(gmp_int& val, std::size_t index)
|
|
2293
|
+
{
|
|
2294
|
+
mpz_clrbit(val.data(), index);
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
inline void eval_bit_flip(gmp_int& val, std::size_t index)
|
|
2298
|
+
{
|
|
2299
|
+
mpz_combit(val.data(), index);
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2302
|
+
inline void eval_qr(const gmp_int& x, const gmp_int& y,
|
|
2303
|
+
gmp_int& q, gmp_int& r)
|
|
2304
|
+
{
|
|
2305
|
+
mpz_tdiv_qr(q.data(), r.data(), x.data(), y.data());
|
|
2306
|
+
}
|
|
2307
|
+
|
|
2308
|
+
template <class Integer>
|
|
2309
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_unsigned<Integer>::value, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val)
|
|
2310
|
+
{
|
|
2311
|
+
#if defined(__MPIR_VERSION) && (__MPIR_VERSION >= 3)
|
|
2312
|
+
if ((sizeof(Integer) <= sizeof(mpir_ui)) || (val <= (std::numeric_limits<mpir_ui>::max)()))
|
|
2313
|
+
#else
|
|
2314
|
+
if ((sizeof(Integer) <= sizeof(long)) || (val <= (std::numeric_limits<unsigned long>::max)()))
|
|
2315
|
+
#endif
|
|
2316
|
+
{
|
|
2317
|
+
return static_cast<Integer>(mpz_tdiv_ui(x.data(), val));
|
|
2318
|
+
}
|
|
2319
|
+
else
|
|
2320
|
+
{
|
|
2321
|
+
return default_ops::eval_integer_modulus(x, val);
|
|
2322
|
+
}
|
|
2323
|
+
}
|
|
2324
|
+
template <class Integer>
|
|
2325
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_signed<Integer>::value && boost::multiprecision::detail::is_integral<Integer>::value, Integer>::type eval_integer_modulus(const gmp_int& x, Integer val)
|
|
2326
|
+
{
|
|
2327
|
+
return eval_integer_modulus(x, boost::multiprecision::detail::unsigned_abs(val));
|
|
2328
|
+
}
|
|
2329
|
+
inline void eval_powm(gmp_int& result, const gmp_int& base, const gmp_int& p, const gmp_int& m)
|
|
2330
|
+
{
|
|
2331
|
+
if (eval_get_sign(p) < 0)
|
|
2332
|
+
{
|
|
2333
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
|
|
2334
|
+
}
|
|
2335
|
+
mpz_powm(result.data(), base.data(), p.data(), m.data());
|
|
2336
|
+
}
|
|
2337
|
+
|
|
2338
|
+
template <class Integer>
|
|
2339
|
+
inline typename std::enable_if<
|
|
2340
|
+
boost::multiprecision::detail::is_unsigned<Integer>::value && (sizeof(Integer) <= sizeof(unsigned long))>::type
|
|
2341
|
+
eval_powm(gmp_int& result, const gmp_int& base, Integer p, const gmp_int& m)
|
|
2342
|
+
{
|
|
2343
|
+
mpz_powm_ui(result.data(), base.data(), p, m.data());
|
|
2344
|
+
}
|
|
2345
|
+
template <class Integer>
|
|
2346
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_signed<Integer>::value && boost::multiprecision::detail::is_integral<Integer>::value && (sizeof(Integer) <= sizeof(unsigned long))>::type
|
|
2347
|
+
eval_powm(gmp_int& result, const gmp_int& base, Integer p, const gmp_int& m)
|
|
2348
|
+
{
|
|
2349
|
+
if (p < 0)
|
|
2350
|
+
{
|
|
2351
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("powm requires a positive exponent."));
|
|
2352
|
+
}
|
|
2353
|
+
mpz_powm_ui(result.data(), base.data(), p, m.data());
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
inline std::size_t hash_value(const gmp_int& val)
|
|
2357
|
+
{
|
|
2358
|
+
// We should really use mpz_limbs_read here, but that's unsupported on older versions:
|
|
2359
|
+
std::size_t result = 0;
|
|
2360
|
+
for (int i = 0; i < std::abs(val.data()[0]._mp_size); ++i)
|
|
2361
|
+
boost::multiprecision::detail::hash_combine(result, val.data()[0]._mp_d[i]);
|
|
2362
|
+
boost::multiprecision::detail::hash_combine(result, val.data()[0]._mp_size);
|
|
2363
|
+
return result;
|
|
2364
|
+
}
|
|
2365
|
+
|
|
2366
|
+
struct gmp_rational;
|
|
2367
|
+
void eval_add(gmp_rational& t, const gmp_rational& o);
|
|
2368
|
+
|
|
2369
|
+
struct gmp_rational
|
|
2370
|
+
{
|
|
2371
|
+
#ifdef BOOST_HAS_LONG_LONG
|
|
2372
|
+
using signed_types = std::tuple<long, long long> ;
|
|
2373
|
+
using unsigned_types = std::tuple<unsigned long, unsigned long long>;
|
|
2374
|
+
#else
|
|
2375
|
+
using signed_types = std::tuple<long> ;
|
|
2376
|
+
using unsigned_types = std::tuple<unsigned long>;
|
|
2377
|
+
#endif
|
|
2378
|
+
using float_types = std::tuple<double, long double>;
|
|
2379
|
+
|
|
2380
|
+
gmp_rational()
|
|
2381
|
+
{
|
|
2382
|
+
mpq_init(this->m_data);
|
|
2383
|
+
}
|
|
2384
|
+
gmp_rational(const gmp_rational& o)
|
|
2385
|
+
{
|
|
2386
|
+
mpq_init(m_data);
|
|
2387
|
+
if (o.m_data[0]._mp_num._mp_d)
|
|
2388
|
+
mpq_set(m_data, o.m_data);
|
|
2389
|
+
}
|
|
2390
|
+
gmp_rational(const gmp_int& o)
|
|
2391
|
+
{
|
|
2392
|
+
mpz_init_set(&m_data[0]._mp_num, o.data());
|
|
2393
|
+
mpz_init_set_ui(&m_data[0]._mp_den, 1u);
|
|
2394
|
+
}
|
|
2395
|
+
gmp_rational(long i)
|
|
2396
|
+
{
|
|
2397
|
+
mpz_init_set_si(&m_data[0]._mp_num, i);
|
|
2398
|
+
mpz_init_set_ui(&m_data[0]._mp_den, 1u);
|
|
2399
|
+
}
|
|
2400
|
+
gmp_rational(unsigned long ui)
|
|
2401
|
+
{
|
|
2402
|
+
mpz_init_set_ui(&m_data[0]._mp_num, ui);
|
|
2403
|
+
mpz_init_set_ui(&m_data[0]._mp_den, 1u);
|
|
2404
|
+
}
|
|
2405
|
+
// 2-arg constructors:
|
|
2406
|
+
template <class T, class U>
|
|
2407
|
+
gmp_rational(const T& a, const U& b, typename std::enable_if<std::is_constructible<gmp_int, T>::value && std::is_constructible<gmp_int, U>::value>::type* = nullptr)
|
|
2408
|
+
{
|
|
2409
|
+
gmp_int i(a), j(b);
|
|
2410
|
+
|
|
2411
|
+
if (eval_is_zero(j))
|
|
2412
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
2413
|
+
|
|
2414
|
+
m_data[0]._mp_num = i.data()[0];
|
|
2415
|
+
m_data[0]._mp_den = j.data()[0];
|
|
2416
|
+
mpq_canonicalize(m_data);
|
|
2417
|
+
i.data()[0]._mp_d = nullptr;
|
|
2418
|
+
j.data()[0]._mp_d = nullptr;
|
|
2419
|
+
}
|
|
2420
|
+
template <class U>
|
|
2421
|
+
gmp_rational(const gmp_int& a, const U& b, typename std::enable_if<std::is_constructible<gmp_int, U>::value>::type* = nullptr)
|
|
2422
|
+
{
|
|
2423
|
+
gmp_int j(b);
|
|
2424
|
+
|
|
2425
|
+
if (eval_is_zero(j))
|
|
2426
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
2427
|
+
|
|
2428
|
+
mpz_init_set(&m_data[0]._mp_num, a.data());
|
|
2429
|
+
m_data[0]._mp_den = j.data()[0];
|
|
2430
|
+
if (boost::multiprecision::detail::unsigned_abs(b) > 1)
|
|
2431
|
+
mpq_canonicalize(m_data);
|
|
2432
|
+
j.data()[0]._mp_d = nullptr;
|
|
2433
|
+
}
|
|
2434
|
+
template <class U>
|
|
2435
|
+
gmp_rational(gmp_int&& a, const U& b, typename std::enable_if<std::is_constructible<gmp_int, U>::value>::type* = nullptr)
|
|
2436
|
+
{
|
|
2437
|
+
gmp_int j(b);
|
|
2438
|
+
|
|
2439
|
+
if (eval_is_zero(j))
|
|
2440
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
2441
|
+
|
|
2442
|
+
m_data[0]._mp_num = a.data()[0];
|
|
2443
|
+
m_data[0]._mp_den = j.data()[0];
|
|
2444
|
+
if (boost::multiprecision::detail::unsigned_abs(b) > 1)
|
|
2445
|
+
mpq_canonicalize(m_data);
|
|
2446
|
+
a.data()[0]._mp_d = nullptr;
|
|
2447
|
+
j.data()[0]._mp_d = nullptr;
|
|
2448
|
+
}
|
|
2449
|
+
template <class T>
|
|
2450
|
+
gmp_rational(const T& a, const gmp_int& b, typename std::enable_if<std::is_constructible<gmp_int, T>::value>::type* = nullptr)
|
|
2451
|
+
{
|
|
2452
|
+
if (eval_is_zero(b))
|
|
2453
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
2454
|
+
|
|
2455
|
+
gmp_int i(a);
|
|
2456
|
+
m_data[0]._mp_num = i.data()[0];
|
|
2457
|
+
mpz_init_set(&m_data[0]._mp_den, b.data());
|
|
2458
|
+
if(boost::multiprecision::detail::unsigned_abs(a) > 1)
|
|
2459
|
+
mpq_canonicalize(m_data);
|
|
2460
|
+
i.data()[0]._mp_d = nullptr;
|
|
2461
|
+
}
|
|
2462
|
+
template <class T>
|
|
2463
|
+
gmp_rational(const T& a, gmp_int&& b, typename std::enable_if<std::is_constructible<gmp_int, T>::value>::type* = nullptr)
|
|
2464
|
+
{
|
|
2465
|
+
if (eval_is_zero(static_cast<gmp_int&&>(b)))
|
|
2466
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
2467
|
+
|
|
2468
|
+
gmp_int i(a);
|
|
2469
|
+
m_data[0]._mp_num = i.data()[0];
|
|
2470
|
+
m_data[0]._mp_den = b.data()[0];
|
|
2471
|
+
if(boost::multiprecision::detail::unsigned_abs(a) > 1)
|
|
2472
|
+
mpq_canonicalize(m_data);
|
|
2473
|
+
i.data()[0]._mp_d = nullptr;
|
|
2474
|
+
b.data()[0]._mp_d = nullptr;
|
|
2475
|
+
}
|
|
2476
|
+
gmp_rational(const gmp_int& a, const gmp_int& b)
|
|
2477
|
+
{
|
|
2478
|
+
if (eval_is_zero(b))
|
|
2479
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
2480
|
+
|
|
2481
|
+
mpz_init_set(&m_data[0]._mp_num, a.data());
|
|
2482
|
+
mpz_init_set(&m_data[0]._mp_den, b.data());
|
|
2483
|
+
mpq_canonicalize(m_data);
|
|
2484
|
+
}
|
|
2485
|
+
gmp_rational(const gmp_int& a, gmp_int&& b)
|
|
2486
|
+
{
|
|
2487
|
+
if (eval_is_zero(static_cast<gmp_int&&>(b)))
|
|
2488
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
2489
|
+
|
|
2490
|
+
mpz_init_set(&m_data[0]._mp_num, a.data());
|
|
2491
|
+
m_data[0]._mp_den = b.data()[0];
|
|
2492
|
+
mpq_canonicalize(m_data);
|
|
2493
|
+
b.data()[0]._mp_d = nullptr;
|
|
2494
|
+
}
|
|
2495
|
+
gmp_rational(gmp_int&& a, const gmp_int& b)
|
|
2496
|
+
{
|
|
2497
|
+
if (eval_is_zero(b))
|
|
2498
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
2499
|
+
|
|
2500
|
+
m_data[0]._mp_num = a.data()[0];
|
|
2501
|
+
mpz_init_set(&m_data[0]._mp_den, b.data());
|
|
2502
|
+
mpq_canonicalize(m_data);
|
|
2503
|
+
a.data()[0]._mp_d = nullptr;
|
|
2504
|
+
}
|
|
2505
|
+
gmp_rational(gmp_int&& a, gmp_int&& b)
|
|
2506
|
+
{
|
|
2507
|
+
if (eval_is_zero(static_cast<gmp_int&&>(b)))
|
|
2508
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
2509
|
+
|
|
2510
|
+
m_data[0]._mp_num = a.data()[0];
|
|
2511
|
+
m_data[0]._mp_den = b.data()[0];
|
|
2512
|
+
mpq_canonicalize(m_data);
|
|
2513
|
+
a.data()[0]._mp_d = nullptr;
|
|
2514
|
+
b.data()[0]._mp_d = nullptr;
|
|
2515
|
+
}
|
|
2516
|
+
// rvalue copy
|
|
2517
|
+
gmp_rational(gmp_rational&& o) noexcept
|
|
2518
|
+
{
|
|
2519
|
+
m_data[0] = o.m_data[0];
|
|
2520
|
+
o.m_data[0]._mp_num._mp_d = nullptr;
|
|
2521
|
+
o.m_data[0]._mp_den._mp_d = nullptr;
|
|
2522
|
+
}
|
|
2523
|
+
gmp_rational(const mpq_t o)
|
|
2524
|
+
{
|
|
2525
|
+
mpq_init(m_data);
|
|
2526
|
+
mpq_set(m_data, o);
|
|
2527
|
+
}
|
|
2528
|
+
gmp_rational(const mpz_t o)
|
|
2529
|
+
{
|
|
2530
|
+
mpq_init(m_data);
|
|
2531
|
+
mpq_set_z(m_data, o);
|
|
2532
|
+
}
|
|
2533
|
+
gmp_rational& operator=(const gmp_rational& o)
|
|
2534
|
+
{
|
|
2535
|
+
if (m_data[0]._mp_den._mp_d == nullptr)
|
|
2536
|
+
mpq_init(m_data);
|
|
2537
|
+
mpq_set(m_data, o.m_data);
|
|
2538
|
+
return *this;
|
|
2539
|
+
}
|
|
2540
|
+
// rvalue assign
|
|
2541
|
+
gmp_rational& operator=(gmp_rational&& o) noexcept
|
|
2542
|
+
{
|
|
2543
|
+
mpq_swap(m_data, o.m_data);
|
|
2544
|
+
return *this;
|
|
2545
|
+
}
|
|
2546
|
+
#ifdef BOOST_HAS_LONG_LONG
|
|
2547
|
+
#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX)
|
|
2548
|
+
gmp_rational& operator=(unsigned long long i)
|
|
2549
|
+
{
|
|
2550
|
+
*this = static_cast<unsigned long>(i);
|
|
2551
|
+
return *this;
|
|
2552
|
+
}
|
|
2553
|
+
#else
|
|
2554
|
+
gmp_rational& operator=(unsigned long long i)
|
|
2555
|
+
{
|
|
2556
|
+
if (m_data[0]._mp_den._mp_d == nullptr)
|
|
2557
|
+
mpq_init(m_data);
|
|
2558
|
+
gmp_int zi;
|
|
2559
|
+
zi = i;
|
|
2560
|
+
mpq_set_z(m_data, zi.data());
|
|
2561
|
+
return *this;
|
|
2562
|
+
}
|
|
2563
|
+
gmp_rational& operator=(long long i)
|
|
2564
|
+
{
|
|
2565
|
+
if (m_data[0]._mp_den._mp_d == nullptr)
|
|
2566
|
+
mpq_init(m_data);
|
|
2567
|
+
bool neg = i < 0;
|
|
2568
|
+
*this = boost::multiprecision::detail::unsigned_abs(i);
|
|
2569
|
+
if (neg)
|
|
2570
|
+
mpq_neg(m_data, m_data);
|
|
2571
|
+
return *this;
|
|
2572
|
+
}
|
|
2573
|
+
#endif
|
|
2574
|
+
#endif
|
|
2575
|
+
gmp_rational& operator=(unsigned long i)
|
|
2576
|
+
{
|
|
2577
|
+
if (m_data[0]._mp_den._mp_d == nullptr)
|
|
2578
|
+
mpq_init(m_data);
|
|
2579
|
+
mpq_set_ui(m_data, i, 1);
|
|
2580
|
+
return *this;
|
|
2581
|
+
}
|
|
2582
|
+
gmp_rational& operator=(long i)
|
|
2583
|
+
{
|
|
2584
|
+
if (m_data[0]._mp_den._mp_d == nullptr)
|
|
2585
|
+
mpq_init(m_data);
|
|
2586
|
+
mpq_set_si(m_data, i, 1);
|
|
2587
|
+
return *this;
|
|
2588
|
+
}
|
|
2589
|
+
gmp_rational& operator=(double d)
|
|
2590
|
+
{
|
|
2591
|
+
if (m_data[0]._mp_den._mp_d == nullptr)
|
|
2592
|
+
mpq_init(m_data);
|
|
2593
|
+
mpq_set_d(m_data, d);
|
|
2594
|
+
return *this;
|
|
2595
|
+
}
|
|
2596
|
+
template <class F>
|
|
2597
|
+
gmp_rational& assign_float(F a)
|
|
2598
|
+
{
|
|
2599
|
+
using default_ops::eval_add;
|
|
2600
|
+
using default_ops::eval_subtract;
|
|
2601
|
+
BOOST_MP_FLOAT128_USING using std::floor; using std::frexp; using std::ldexp;
|
|
2602
|
+
|
|
2603
|
+
if (m_data[0]._mp_den._mp_d == nullptr)
|
|
2604
|
+
mpq_init(m_data);
|
|
2605
|
+
|
|
2606
|
+
if (a == 0)
|
|
2607
|
+
{
|
|
2608
|
+
mpq_set_si(m_data, 0, 1);
|
|
2609
|
+
return *this;
|
|
2610
|
+
}
|
|
2611
|
+
|
|
2612
|
+
if (a == 1)
|
|
2613
|
+
{
|
|
2614
|
+
mpq_set_si(m_data, 1, 1);
|
|
2615
|
+
return *this;
|
|
2616
|
+
}
|
|
2617
|
+
|
|
2618
|
+
BOOST_MP_ASSERT(!BOOST_MP_ISINF(a));
|
|
2619
|
+
BOOST_MP_ASSERT(!BOOST_MP_ISNAN(a));
|
|
2620
|
+
|
|
2621
|
+
int e;
|
|
2622
|
+
F f, term;
|
|
2623
|
+
mpq_set_ui(m_data, 0, 1);
|
|
2624
|
+
mpq_set_ui(m_data, 0u, 1);
|
|
2625
|
+
gmp_rational t;
|
|
2626
|
+
|
|
2627
|
+
f = frexp(a, &e);
|
|
2628
|
+
|
|
2629
|
+
constexpr int shift = std::numeric_limits<int>::digits - 1;
|
|
2630
|
+
|
|
2631
|
+
while (f != static_cast<F>(0.0f))
|
|
2632
|
+
{
|
|
2633
|
+
// extract int sized bits from f:
|
|
2634
|
+
f = ldexp(f, shift);
|
|
2635
|
+
term = floor(f);
|
|
2636
|
+
e -= shift;
|
|
2637
|
+
mpq_mul_2exp(m_data, m_data, shift);
|
|
2638
|
+
t = static_cast<long>(term);
|
|
2639
|
+
eval_add(*this, t);
|
|
2640
|
+
f -= term;
|
|
2641
|
+
}
|
|
2642
|
+
if (e > 0)
|
|
2643
|
+
mpq_mul_2exp(m_data, m_data, static_cast<mp_bitcnt_t>(e));
|
|
2644
|
+
else if (e < 0)
|
|
2645
|
+
mpq_div_2exp(m_data, m_data, static_cast<mp_bitcnt_t>(-e));
|
|
2646
|
+
return *this;
|
|
2647
|
+
}
|
|
2648
|
+
gmp_rational& operator=(long double a)
|
|
2649
|
+
{
|
|
2650
|
+
return assign_float(a);
|
|
2651
|
+
}
|
|
2652
|
+
#ifdef BOOST_HAS_FLOAT128
|
|
2653
|
+
gmp_rational& operator=(float128_type a)
|
|
2654
|
+
{
|
|
2655
|
+
return assign_float(a);
|
|
2656
|
+
}
|
|
2657
|
+
#endif
|
|
2658
|
+
#ifdef BOOST_HAS_INT128
|
|
2659
|
+
gmp_rational& operator=(uint128_type i)
|
|
2660
|
+
{
|
|
2661
|
+
gmp_int gi;
|
|
2662
|
+
gi = i;
|
|
2663
|
+
return *this = gi;
|
|
2664
|
+
}
|
|
2665
|
+
gmp_rational& operator=(int128_type i)
|
|
2666
|
+
{
|
|
2667
|
+
gmp_int gi;
|
|
2668
|
+
gi = i;
|
|
2669
|
+
return *this = gi;
|
|
2670
|
+
}
|
|
2671
|
+
#endif
|
|
2672
|
+
gmp_rational& operator=(const char* s)
|
|
2673
|
+
{
|
|
2674
|
+
if (m_data[0]._mp_den._mp_d == nullptr)
|
|
2675
|
+
mpq_init(m_data);
|
|
2676
|
+
if (0 != mpq_set_str(m_data, s, 10))
|
|
2677
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error(std::string("The string \"") + s + std::string("\"could not be interpreted as a valid rational number.")));
|
|
2678
|
+
return *this;
|
|
2679
|
+
}
|
|
2680
|
+
gmp_rational& operator=(const gmp_int& o)
|
|
2681
|
+
{
|
|
2682
|
+
if (m_data[0]._mp_den._mp_d == nullptr)
|
|
2683
|
+
mpq_init(m_data);
|
|
2684
|
+
mpq_set_z(m_data, o.data());
|
|
2685
|
+
return *this;
|
|
2686
|
+
}
|
|
2687
|
+
gmp_rational& operator=(const mpq_t o)
|
|
2688
|
+
{
|
|
2689
|
+
if (m_data[0]._mp_den._mp_d == nullptr)
|
|
2690
|
+
mpq_init(m_data);
|
|
2691
|
+
mpq_set(m_data, o);
|
|
2692
|
+
return *this;
|
|
2693
|
+
}
|
|
2694
|
+
gmp_rational& operator=(const mpz_t o)
|
|
2695
|
+
{
|
|
2696
|
+
if (m_data[0]._mp_den._mp_d == nullptr)
|
|
2697
|
+
mpq_init(m_data);
|
|
2698
|
+
mpq_set_z(m_data, o);
|
|
2699
|
+
return *this;
|
|
2700
|
+
}
|
|
2701
|
+
void swap(gmp_rational& o)
|
|
2702
|
+
{
|
|
2703
|
+
mpq_swap(m_data, o.m_data);
|
|
2704
|
+
}
|
|
2705
|
+
std::string str(std::streamsize /*digits*/, std::ios_base::fmtflags /*f*/) const
|
|
2706
|
+
{
|
|
2707
|
+
BOOST_MP_ASSERT(m_data[0]._mp_num._mp_d);
|
|
2708
|
+
// TODO make a better job of this including handling of f!!
|
|
2709
|
+
void* (*alloc_func_ptr)(size_t);
|
|
2710
|
+
void* (*realloc_func_ptr)(void*, size_t, size_t);
|
|
2711
|
+
void (*free_func_ptr)(void*, size_t);
|
|
2712
|
+
const char* ps = mpq_get_str(nullptr, 10, m_data);
|
|
2713
|
+
std::string s = ps;
|
|
2714
|
+
mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
|
|
2715
|
+
(*free_func_ptr)((void*)ps, std::strlen(ps) + 1);
|
|
2716
|
+
return s;
|
|
2717
|
+
}
|
|
2718
|
+
~gmp_rational()
|
|
2719
|
+
{
|
|
2720
|
+
if (m_data[0]._mp_num._mp_d || m_data[0]._mp_den._mp_d)
|
|
2721
|
+
mpq_clear(m_data);
|
|
2722
|
+
}
|
|
2723
|
+
void negate()
|
|
2724
|
+
{
|
|
2725
|
+
BOOST_MP_ASSERT(m_data[0]._mp_num._mp_d);
|
|
2726
|
+
mpq_neg(m_data, m_data);
|
|
2727
|
+
}
|
|
2728
|
+
int compare(const gmp_rational& o) const
|
|
2729
|
+
{
|
|
2730
|
+
BOOST_MP_ASSERT(m_data[0]._mp_num._mp_d && o.m_data[0]._mp_num._mp_d);
|
|
2731
|
+
return mpq_cmp(m_data, o.m_data);
|
|
2732
|
+
}
|
|
2733
|
+
template <class V>
|
|
2734
|
+
int compare(V v) const
|
|
2735
|
+
{
|
|
2736
|
+
gmp_rational d;
|
|
2737
|
+
d = v;
|
|
2738
|
+
return compare(d);
|
|
2739
|
+
}
|
|
2740
|
+
int compare(unsigned long v) const
|
|
2741
|
+
{
|
|
2742
|
+
BOOST_MP_ASSERT(m_data[0]._mp_num._mp_d);
|
|
2743
|
+
return mpq_cmp_ui(m_data, v, 1);
|
|
2744
|
+
}
|
|
2745
|
+
int compare(long v) const
|
|
2746
|
+
{
|
|
2747
|
+
BOOST_MP_ASSERT(m_data[0]._mp_num._mp_d);
|
|
2748
|
+
return mpq_cmp_si(m_data, v, 1);
|
|
2749
|
+
}
|
|
2750
|
+
mpq_t& data()
|
|
2751
|
+
{
|
|
2752
|
+
BOOST_MP_ASSERT(m_data[0]._mp_num._mp_d);
|
|
2753
|
+
return m_data;
|
|
2754
|
+
}
|
|
2755
|
+
const mpq_t& data() const
|
|
2756
|
+
{
|
|
2757
|
+
BOOST_MP_ASSERT(m_data[0]._mp_num._mp_d);
|
|
2758
|
+
return m_data;
|
|
2759
|
+
}
|
|
2760
|
+
|
|
2761
|
+
protected:
|
|
2762
|
+
mpq_t m_data;
|
|
2763
|
+
};
|
|
2764
|
+
|
|
2765
|
+
inline bool eval_is_zero(const gmp_rational& val)
|
|
2766
|
+
{
|
|
2767
|
+
return mpq_sgn(val.data()) == 0;
|
|
2768
|
+
}
|
|
2769
|
+
template <class T>
|
|
2770
|
+
inline bool eval_eq(gmp_rational& a, const T& b)
|
|
2771
|
+
{
|
|
2772
|
+
return a.compare(b) == 0;
|
|
2773
|
+
}
|
|
2774
|
+
template <class T>
|
|
2775
|
+
inline bool eval_lt(gmp_rational& a, const T& b)
|
|
2776
|
+
{
|
|
2777
|
+
return a.compare(b) < 0;
|
|
2778
|
+
}
|
|
2779
|
+
template <class T>
|
|
2780
|
+
inline bool eval_gt(gmp_rational& a, const T& b)
|
|
2781
|
+
{
|
|
2782
|
+
return a.compare(b) > 0;
|
|
2783
|
+
}
|
|
2784
|
+
|
|
2785
|
+
inline void eval_add(gmp_rational& t, const gmp_rational& o)
|
|
2786
|
+
{
|
|
2787
|
+
mpq_add(t.data(), t.data(), o.data());
|
|
2788
|
+
}
|
|
2789
|
+
inline void eval_subtract(gmp_rational& t, const gmp_rational& o)
|
|
2790
|
+
{
|
|
2791
|
+
mpq_sub(t.data(), t.data(), o.data());
|
|
2792
|
+
}
|
|
2793
|
+
inline void eval_multiply(gmp_rational& t, const gmp_rational& o)
|
|
2794
|
+
{
|
|
2795
|
+
mpq_mul(t.data(), t.data(), o.data());
|
|
2796
|
+
}
|
|
2797
|
+
inline void eval_divide(gmp_rational& t, const gmp_rational& o)
|
|
2798
|
+
{
|
|
2799
|
+
if (eval_is_zero(o))
|
|
2800
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
2801
|
+
mpq_div(t.data(), t.data(), o.data());
|
|
2802
|
+
}
|
|
2803
|
+
inline void eval_add(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
|
|
2804
|
+
{
|
|
2805
|
+
mpq_add(t.data(), p.data(), o.data());
|
|
2806
|
+
}
|
|
2807
|
+
inline void eval_subtract(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
|
|
2808
|
+
{
|
|
2809
|
+
mpq_sub(t.data(), p.data(), o.data());
|
|
2810
|
+
}
|
|
2811
|
+
inline void eval_multiply(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
|
|
2812
|
+
{
|
|
2813
|
+
mpq_mul(t.data(), p.data(), o.data());
|
|
2814
|
+
}
|
|
2815
|
+
inline void eval_divide(gmp_rational& t, const gmp_rational& p, const gmp_rational& o)
|
|
2816
|
+
{
|
|
2817
|
+
if (eval_is_zero(o))
|
|
2818
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
2819
|
+
mpq_div(t.data(), p.data(), o.data());
|
|
2820
|
+
}
|
|
2821
|
+
//
|
|
2822
|
+
// operator with scalars:
|
|
2823
|
+
//
|
|
2824
|
+
inline void eval_add(gmp_rational& result, gmp_rational const& a, gmp_int const& b)
|
|
2825
|
+
{
|
|
2826
|
+
// we allow result and a to be the same object here:
|
|
2827
|
+
if (&a != &result)
|
|
2828
|
+
{
|
|
2829
|
+
mpz_set(mpq_numref(result.data()), mpq_numref(a.data()));
|
|
2830
|
+
mpz_set(mpq_denref(result.data()), mpq_denref(a.data()));
|
|
2831
|
+
}
|
|
2832
|
+
mpz_addmul(mpq_numref(result.data()), mpq_denref(a.data()), b.data());
|
|
2833
|
+
// no need to normalize, there can be no common divisor as long as a is already normalized.
|
|
2834
|
+
}
|
|
2835
|
+
inline void eval_add(gmp_rational& result, gmp_rational const& a, unsigned long b)
|
|
2836
|
+
{
|
|
2837
|
+
// we allow result and a to be the same object here:
|
|
2838
|
+
if (&a != &result)
|
|
2839
|
+
{
|
|
2840
|
+
mpz_set(mpq_numref(result.data()), mpq_numref(a.data()));
|
|
2841
|
+
mpz_set(mpq_denref(result.data()), mpq_denref(a.data()));
|
|
2842
|
+
}
|
|
2843
|
+
mpz_addmul_ui(mpq_numref(result.data()), mpq_denref(a.data()), b);
|
|
2844
|
+
// no need to normalize, there can be no common divisor as long as a is already normalized.
|
|
2845
|
+
}
|
|
2846
|
+
inline void eval_add(gmp_rational& result, gmp_rational const& a, long b)
|
|
2847
|
+
{
|
|
2848
|
+
// we allow result and a to be the same object here:
|
|
2849
|
+
if (&a != &result)
|
|
2850
|
+
{
|
|
2851
|
+
mpz_set(mpq_numref(result.data()), mpq_numref(a.data()));
|
|
2852
|
+
mpz_set(mpq_denref(result.data()), mpq_denref(a.data()));
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2855
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
2856
|
+
|
|
2857
|
+
if(b > 0)
|
|
2858
|
+
mpz_addmul_ui(mpq_numref(result.data()), mpq_denref(a.data()), static_cast<local_uint_type>(b));
|
|
2859
|
+
else
|
|
2860
|
+
mpz_submul_ui(mpq_numref(result.data()), mpq_denref(a.data()), static_cast<local_uint_type>(-b));
|
|
2861
|
+
// no need to normalize, there can be no common divisor as long as a is already normalized.
|
|
2862
|
+
}
|
|
2863
|
+
template <class T>
|
|
2864
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_integral<T>::value>::type eval_add(gmp_rational& result, gmp_rational const& a, const T& b)
|
|
2865
|
+
{
|
|
2866
|
+
gmp_int t;
|
|
2867
|
+
t = b;
|
|
2868
|
+
eval_add(result, a, t);
|
|
2869
|
+
}
|
|
2870
|
+
template <class T>
|
|
2871
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_integral<T>::value>::type eval_add(gmp_rational& result, const T& b, gmp_rational const& a)
|
|
2872
|
+
{
|
|
2873
|
+
eval_add(result, a, b);
|
|
2874
|
+
}
|
|
2875
|
+
template <class T>
|
|
2876
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_integral<T>::value>::type eval_add(gmp_rational& result, const T& b)
|
|
2877
|
+
{
|
|
2878
|
+
eval_add(result, result, b);
|
|
2879
|
+
}
|
|
2880
|
+
inline void eval_subtract(gmp_rational& result, gmp_rational const& a, gmp_int const& b)
|
|
2881
|
+
{
|
|
2882
|
+
// we allow result and a to be the same object here:
|
|
2883
|
+
if (&a != &result)
|
|
2884
|
+
{
|
|
2885
|
+
mpz_set(mpq_numref(result.data()), mpq_numref(a.data()));
|
|
2886
|
+
mpz_set(mpq_denref(result.data()), mpq_denref(a.data()));
|
|
2887
|
+
}
|
|
2888
|
+
mpz_submul(mpq_numref(result.data()), mpq_denref(a.data()), b.data());
|
|
2889
|
+
// no need to normalize, there can be no common divisor as long as a is already normalized.
|
|
2890
|
+
}
|
|
2891
|
+
inline void eval_subtract(gmp_rational& result, gmp_rational const& a, unsigned long b)
|
|
2892
|
+
{
|
|
2893
|
+
// we allow result and a to be the same object here:
|
|
2894
|
+
if (&a != &result)
|
|
2895
|
+
{
|
|
2896
|
+
mpz_set(mpq_numref(result.data()), mpq_numref(a.data()));
|
|
2897
|
+
mpz_set(mpq_denref(result.data()), mpq_denref(a.data()));
|
|
2898
|
+
}
|
|
2899
|
+
mpz_submul_ui(mpq_numref(result.data()), mpq_denref(a.data()), b);
|
|
2900
|
+
// no need to normalize, there can be no common divisor as long as a is already normalized.
|
|
2901
|
+
}
|
|
2902
|
+
inline void eval_subtract(gmp_rational& result, gmp_rational const& a, long b)
|
|
2903
|
+
{
|
|
2904
|
+
// we allow result and a to be the same object here:
|
|
2905
|
+
if (&a != &result)
|
|
2906
|
+
{
|
|
2907
|
+
mpz_set(mpq_numref(result.data()), mpq_numref(a.data()));
|
|
2908
|
+
mpz_set(mpq_denref(result.data()), mpq_denref(a.data()));
|
|
2909
|
+
}
|
|
2910
|
+
|
|
2911
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
2912
|
+
|
|
2913
|
+
if(b > 0)
|
|
2914
|
+
mpz_submul_ui(mpq_numref(result.data()), mpq_denref(a.data()), static_cast<local_uint_type>(b));
|
|
2915
|
+
else
|
|
2916
|
+
mpz_addmul_ui(mpq_numref(result.data()), mpq_denref(a.data()), static_cast<local_uint_type>(-b));
|
|
2917
|
+
// no need to normalize, there can be no common divisor as long as a is already normalized.
|
|
2918
|
+
}
|
|
2919
|
+
template <class T>
|
|
2920
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_integral<T>::value>::type eval_subtract(gmp_rational& result, gmp_rational const& a, const T& b)
|
|
2921
|
+
{
|
|
2922
|
+
gmp_int t;
|
|
2923
|
+
t = b;
|
|
2924
|
+
eval_subtract(result, a, t);
|
|
2925
|
+
}
|
|
2926
|
+
template <class T>
|
|
2927
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_integral<T>::value>::type eval_subtract(gmp_rational& result, const T& b, gmp_rational const& a)
|
|
2928
|
+
{
|
|
2929
|
+
eval_subtract(result, a, b);
|
|
2930
|
+
result.negate();
|
|
2931
|
+
}
|
|
2932
|
+
template <class T>
|
|
2933
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_integral<T>::value>::type eval_subtract(gmp_rational& result, const T& b)
|
|
2934
|
+
{
|
|
2935
|
+
eval_subtract(result, result, b);
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2938
|
+
inline void eval_multiply(gmp_rational& result, gmp_rational const& a, gmp_int const& b)
|
|
2939
|
+
{
|
|
2940
|
+
gmp_int g, t;
|
|
2941
|
+
mpz_gcd(g.data(), mpq_denref(a.data()), b.data());
|
|
2942
|
+
if (!mpz_fits_uint_p(g.data()) || (mpz_get_ui(g.data()) != 1))
|
|
2943
|
+
{
|
|
2944
|
+
// We get here if the gcd is not unity, this is true if the number is
|
|
2945
|
+
// too large for an unsigned long, or if we get an unsigned long and check against 1.
|
|
2946
|
+
eval_divide(t, b, g);
|
|
2947
|
+
mpz_mul(mpq_numref(result.data()), t.data(), mpq_numref(a.data()));
|
|
2948
|
+
mpz_divexact(mpq_denref(result.data()), mpq_denref(a.data()), g.data());
|
|
2949
|
+
}
|
|
2950
|
+
else
|
|
2951
|
+
{
|
|
2952
|
+
// gcd is 1.
|
|
2953
|
+
mpz_mul(mpq_numref(result.data()), mpq_numref(a.data()), b.data());
|
|
2954
|
+
if (&result != &a)
|
|
2955
|
+
mpz_set(mpq_denref(result.data()), mpq_denref(a.data()));
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
inline void eval_multiply(gmp_rational& result, gmp_rational const& a, unsigned long b)
|
|
2959
|
+
{
|
|
2960
|
+
if (b == 0)
|
|
2961
|
+
{
|
|
2962
|
+
mpq_set_ui(result.data(), b, 1);
|
|
2963
|
+
return;
|
|
2964
|
+
}
|
|
2965
|
+
if (mpz_sgn(mpq_numref(a.data())) == 0)
|
|
2966
|
+
{
|
|
2967
|
+
result = a;
|
|
2968
|
+
return;
|
|
2969
|
+
}
|
|
2970
|
+
unsigned long g = static_cast<unsigned long>(mpz_gcd_ui(nullptr, mpq_denref(a.data()), b));
|
|
2971
|
+
if (g != 1)
|
|
2972
|
+
{
|
|
2973
|
+
BOOST_MP_ASSERT(g);
|
|
2974
|
+
b /= g;
|
|
2975
|
+
mpz_mul_ui(mpq_numref(result.data()), mpq_numref(a.data()), b);
|
|
2976
|
+
mpz_divexact_ui(mpq_denref(result.data()), mpq_denref(a.data()), g);
|
|
2977
|
+
}
|
|
2978
|
+
else
|
|
2979
|
+
{
|
|
2980
|
+
mpz_mul_ui(mpq_numref(result.data()), mpq_numref(a.data()), b);
|
|
2981
|
+
if (&result != &a)
|
|
2982
|
+
mpz_set(mpq_denref(result.data()), mpq_denref(a.data()));
|
|
2983
|
+
}
|
|
2984
|
+
}
|
|
2985
|
+
inline void eval_multiply(gmp_rational& result, gmp_rational const& a, long b)
|
|
2986
|
+
{
|
|
2987
|
+
eval_multiply(result, a, boost::multiprecision::detail::unsigned_abs(b));
|
|
2988
|
+
if (b < 0)
|
|
2989
|
+
result.negate();
|
|
2990
|
+
}
|
|
2991
|
+
template <class T>
|
|
2992
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_integral<T>::value>::type eval_multiply(gmp_rational& result, gmp_rational const& a, const T& b)
|
|
2993
|
+
{
|
|
2994
|
+
gmp_int t;
|
|
2995
|
+
t = b;
|
|
2996
|
+
eval_multiply(result, a, t);
|
|
2997
|
+
}
|
|
2998
|
+
template <class T>
|
|
2999
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_integral<T>::value>::type eval_multiply(gmp_rational& result, const T& b, gmp_rational const& a)
|
|
3000
|
+
{
|
|
3001
|
+
eval_multiply(result, a, b);
|
|
3002
|
+
}
|
|
3003
|
+
template <class T>
|
|
3004
|
+
inline typename std::enable_if<boost::multiprecision::detail::is_integral<T>::value>::type eval_multiply(gmp_rational& result, const T& b)
|
|
3005
|
+
{
|
|
3006
|
+
eval_multiply(result, result, b);
|
|
3007
|
+
}
|
|
3008
|
+
|
|
3009
|
+
inline int eval_get_sign(const gmp_rational& val)
|
|
3010
|
+
{
|
|
3011
|
+
return mpq_sgn(val.data());
|
|
3012
|
+
}
|
|
3013
|
+
template <class R>
|
|
3014
|
+
inline typename std::enable_if<number_category<R>::value == number_kind_floating_point>::type eval_convert_to(R* result, const gmp_rational& backend)
|
|
3015
|
+
{
|
|
3016
|
+
//
|
|
3017
|
+
// The generic conversion is as good as anything we can write here:
|
|
3018
|
+
//
|
|
3019
|
+
// This does not round correctly:
|
|
3020
|
+
//
|
|
3021
|
+
//*result = mpq_get_d(val.data());
|
|
3022
|
+
//
|
|
3023
|
+
// This does:
|
|
3024
|
+
//
|
|
3025
|
+
::boost::multiprecision::detail::generic_convert_rational_to_float(*result, backend);
|
|
3026
|
+
}
|
|
3027
|
+
#ifdef BOOST_HAS_FLOAT128
|
|
3028
|
+
inline void eval_convert_to(float128_type* result, const gmp_rational& val)
|
|
3029
|
+
{
|
|
3030
|
+
using default_ops::eval_convert_to;
|
|
3031
|
+
|
|
3032
|
+
gmp_int n, d;
|
|
3033
|
+
float128_type fn, fd;
|
|
3034
|
+
mpz_set(n.data(), mpq_numref(val.data()));
|
|
3035
|
+
mpz_set(d.data(), mpq_denref(val.data()));
|
|
3036
|
+
|
|
3037
|
+
eval_convert_to(&fn, n);
|
|
3038
|
+
eval_convert_to(&fd, d);
|
|
3039
|
+
|
|
3040
|
+
*result = fn / fd;
|
|
3041
|
+
}
|
|
3042
|
+
#endif
|
|
3043
|
+
|
|
3044
|
+
template <class R>
|
|
3045
|
+
inline typename std::enable_if<number_category<R>::value == number_kind_integer>::type eval_convert_to(R* result, const gmp_rational& backend)
|
|
3046
|
+
{
|
|
3047
|
+
gmp_int n(mpq_numref(backend.data()));
|
|
3048
|
+
gmp_int d(mpq_denref(backend.data()));
|
|
3049
|
+
using default_ops::eval_divide;
|
|
3050
|
+
eval_divide(n, d);
|
|
3051
|
+
using default_ops::eval_convert_to;
|
|
3052
|
+
eval_convert_to(result, n);
|
|
3053
|
+
}
|
|
3054
|
+
|
|
3055
|
+
inline void eval_abs(gmp_rational& result, const gmp_rational& val)
|
|
3056
|
+
{
|
|
3057
|
+
mpq_abs(result.data(), val.data());
|
|
3058
|
+
}
|
|
3059
|
+
|
|
3060
|
+
inline void assign_components(gmp_rational& result, unsigned long v1, unsigned long v2)
|
|
3061
|
+
{
|
|
3062
|
+
if (v2 == 0u)
|
|
3063
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
3064
|
+
|
|
3065
|
+
mpq_set_ui(result.data(), v1, v2);
|
|
3066
|
+
mpq_canonicalize(result.data());
|
|
3067
|
+
}
|
|
3068
|
+
inline void assign_components(gmp_rational& result, long v1, long v2)
|
|
3069
|
+
{
|
|
3070
|
+
if (v2 == 0)
|
|
3071
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
3072
|
+
|
|
3073
|
+
using local_uint_type = typename boost::multiprecision::detail::make_unsigned<long>::type;
|
|
3074
|
+
|
|
3075
|
+
if (v2 < 0)
|
|
3076
|
+
mpq_set_si(result.data(), -v1, static_cast<local_uint_type>(-v2));
|
|
3077
|
+
else
|
|
3078
|
+
mpq_set_si(result.data(), v1, static_cast<local_uint_type>(v2));
|
|
3079
|
+
|
|
3080
|
+
mpq_canonicalize(result.data());
|
|
3081
|
+
}
|
|
3082
|
+
inline void assign_components(gmp_rational& result, gmp_int const& v1, gmp_int const& v2)
|
|
3083
|
+
{
|
|
3084
|
+
if (eval_is_zero(v2))
|
|
3085
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
3086
|
+
|
|
3087
|
+
mpz_set(mpq_numref(result.data()), v1.data());
|
|
3088
|
+
mpz_set(mpq_denref(result.data()), v2.data());
|
|
3089
|
+
mpq_canonicalize(result.data());
|
|
3090
|
+
}
|
|
3091
|
+
template <class T, class U>
|
|
3092
|
+
void assign_components(gmp_rational& result, const T& a, const U& b)
|
|
3093
|
+
{
|
|
3094
|
+
gmp_int x, y;
|
|
3095
|
+
|
|
3096
|
+
x = a;
|
|
3097
|
+
y = b;
|
|
3098
|
+
|
|
3099
|
+
if (eval_is_zero(y))
|
|
3100
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
3101
|
+
|
|
3102
|
+
std::swap(result.data()[0]._mp_num, x.data()[0]);
|
|
3103
|
+
std::swap(result.data()[0]._mp_den, y.data()[0]);
|
|
3104
|
+
mpq_canonicalize(result.data());
|
|
3105
|
+
}
|
|
3106
|
+
template <class U>
|
|
3107
|
+
void assign_components(gmp_rational& result, const gmp_int& a, const U& b)
|
|
3108
|
+
{
|
|
3109
|
+
gmp_int y;
|
|
3110
|
+
|
|
3111
|
+
y = b;
|
|
3112
|
+
|
|
3113
|
+
if (eval_is_zero(y))
|
|
3114
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
3115
|
+
|
|
3116
|
+
mpz_set(&result.data()[0]._mp_num, a.data());
|
|
3117
|
+
std::swap(result.data()[0]._mp_den, y.data()[0]);
|
|
3118
|
+
mpq_canonicalize(result.data());
|
|
3119
|
+
}
|
|
3120
|
+
template <class T>
|
|
3121
|
+
void assign_components(gmp_rational& result, const T& a, const gmp_int& b)
|
|
3122
|
+
{
|
|
3123
|
+
if (eval_is_zero(b))
|
|
3124
|
+
BOOST_MP_THROW_EXCEPTION(std::overflow_error("Division by zero."));
|
|
3125
|
+
|
|
3126
|
+
gmp_int x;
|
|
3127
|
+
x = a;
|
|
3128
|
+
std::swap(result.data()[0]._mp_num, x.data()[0]);
|
|
3129
|
+
mpz_set(&result.data()[0]._mp_den, b.data());
|
|
3130
|
+
mpq_canonicalize(result.data());
|
|
3131
|
+
}
|
|
3132
|
+
|
|
3133
|
+
|
|
3134
|
+
inline std::size_t hash_value(const gmp_rational& val)
|
|
3135
|
+
{
|
|
3136
|
+
std::size_t result = 0;
|
|
3137
|
+
for (int i = 0; i < std::abs(val.data()[0]._mp_num._mp_size); ++i)
|
|
3138
|
+
boost::multiprecision::detail::hash_combine(result, val.data()[0]._mp_num._mp_d[i]);
|
|
3139
|
+
for (int i = 0; i < std::abs(val.data()[0]._mp_den._mp_size); ++i)
|
|
3140
|
+
boost::multiprecision::detail::hash_combine(result, val.data()[0]._mp_den._mp_d[i]);
|
|
3141
|
+
boost::multiprecision::detail::hash_combine(result, val.data()[0]._mp_num._mp_size);
|
|
3142
|
+
return result;
|
|
3143
|
+
}
|
|
3144
|
+
|
|
3145
|
+
//
|
|
3146
|
+
// Some useful helpers:
|
|
3147
|
+
//
|
|
3148
|
+
inline std::size_t used_gmp_int_bits(const gmp_int& val)
|
|
3149
|
+
{
|
|
3150
|
+
return eval_msb(val) - eval_lsb(val) + 1;
|
|
3151
|
+
}
|
|
3152
|
+
inline std::size_t used_gmp_rational_bits(const gmp_rational& val)
|
|
3153
|
+
{
|
|
3154
|
+
unsigned d2_d = static_cast<unsigned>(mpz_sizeinbase(mpq_denref(val.data()), 2) - mpz_scan1(mpq_denref(val.data()), 0));
|
|
3155
|
+
unsigned d2_n = static_cast<unsigned>(mpz_sizeinbase(mpq_numref(val.data()), 2) - mpz_scan1(mpq_numref(val.data()), 0));
|
|
3156
|
+
return (std::max)(d2_d, d2_n);
|
|
3157
|
+
}
|
|
3158
|
+
|
|
3159
|
+
//
|
|
3160
|
+
// Some member functions that are dependent upon previous code go here:
|
|
3161
|
+
//
|
|
3162
|
+
template <unsigned Digits10>
|
|
3163
|
+
template <unsigned D>
|
|
3164
|
+
inline gmp_float<Digits10>::gmp_float(const gmp_float<D>& o, typename std::enable_if<D <= Digits10>::type*)
|
|
3165
|
+
{
|
|
3166
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : (unsigned)this->get_default_precision()));
|
|
3167
|
+
mpf_set(this->m_data, o.data());
|
|
3168
|
+
}
|
|
3169
|
+
template <unsigned Digits10>
|
|
3170
|
+
template <unsigned D>
|
|
3171
|
+
inline gmp_float<Digits10>::gmp_float(const gmp_float<D>& o, typename std::enable_if< !(D <= Digits10)>::type*)
|
|
3172
|
+
{
|
|
3173
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : (unsigned)this->get_default_precision()));
|
|
3174
|
+
mpf_set(this->m_data, o.data());
|
|
3175
|
+
}
|
|
3176
|
+
template <unsigned Digits10>
|
|
3177
|
+
inline gmp_float<Digits10>::gmp_float(const gmp_int& o)
|
|
3178
|
+
{
|
|
3179
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : (unsigned)this->get_default_precision()));
|
|
3180
|
+
mpf_set_z(this->data(), o.data());
|
|
3181
|
+
}
|
|
3182
|
+
template <unsigned Digits10>
|
|
3183
|
+
inline gmp_float<Digits10>::gmp_float(const gmp_rational& o)
|
|
3184
|
+
{
|
|
3185
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : (unsigned)this->get_default_precision()));
|
|
3186
|
+
mpf_set_q(this->data(), o.data());
|
|
3187
|
+
}
|
|
3188
|
+
template <unsigned Digits10>
|
|
3189
|
+
template <unsigned D>
|
|
3190
|
+
inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_float<D>& o)
|
|
3191
|
+
{
|
|
3192
|
+
if (this->m_data[0]._mp_d == nullptr)
|
|
3193
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : (unsigned)this->get_default_precision()));
|
|
3194
|
+
mpf_set(this->m_data, o.data());
|
|
3195
|
+
return *this;
|
|
3196
|
+
}
|
|
3197
|
+
template <unsigned Digits10>
|
|
3198
|
+
inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_int& o)
|
|
3199
|
+
{
|
|
3200
|
+
if (this->m_data[0]._mp_d == nullptr)
|
|
3201
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : (unsigned)this->get_default_precision()));
|
|
3202
|
+
mpf_set_z(this->data(), o.data());
|
|
3203
|
+
return *this;
|
|
3204
|
+
}
|
|
3205
|
+
template <unsigned Digits10>
|
|
3206
|
+
inline gmp_float<Digits10>& gmp_float<Digits10>::operator=(const gmp_rational& o)
|
|
3207
|
+
{
|
|
3208
|
+
if (this->m_data[0]._mp_d == nullptr)
|
|
3209
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(Digits10 ? Digits10 : (unsigned)this->get_default_precision()));
|
|
3210
|
+
mpf_set_q(this->data(), o.data());
|
|
3211
|
+
return *this;
|
|
3212
|
+
}
|
|
3213
|
+
inline gmp_float<0>::gmp_float(const gmp_int& o) : requested_precision(get_default_precision())
|
|
3214
|
+
{
|
|
3215
|
+
if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
|
|
3216
|
+
{
|
|
3217
|
+
std::size_t d2 = used_gmp_int_bits(o);
|
|
3218
|
+
std::size_t d10 = 1 + multiprecision::detail::digits2_2_10(d2);
|
|
3219
|
+
if (d10 > requested_precision)
|
|
3220
|
+
requested_precision = static_cast<unsigned>(d10);
|
|
3221
|
+
}
|
|
3222
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
|
|
3223
|
+
mpf_set_z(this->data(), o.data());
|
|
3224
|
+
}
|
|
3225
|
+
inline gmp_float<0>::gmp_float(const gmp_rational& o) : requested_precision(get_default_precision())
|
|
3226
|
+
{
|
|
3227
|
+
if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
|
|
3228
|
+
{
|
|
3229
|
+
std::size_t d10 = 1 + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(o));
|
|
3230
|
+
if (d10 > requested_precision)
|
|
3231
|
+
requested_precision = static_cast<unsigned>(d10);
|
|
3232
|
+
}
|
|
3233
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
|
|
3234
|
+
mpf_set_q(this->data(), o.data());
|
|
3235
|
+
}
|
|
3236
|
+
inline gmp_float<0>& gmp_float<0>::operator=(const gmp_int& o)
|
|
3237
|
+
{
|
|
3238
|
+
if (this->m_data[0]._mp_d == nullptr)
|
|
3239
|
+
{
|
|
3240
|
+
requested_precision = this->get_default_precision();
|
|
3241
|
+
if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
|
|
3242
|
+
{
|
|
3243
|
+
std::size_t d2 = used_gmp_int_bits(o);
|
|
3244
|
+
std::size_t d10 = 1 + multiprecision::detail::digits2_2_10(d2);
|
|
3245
|
+
if (d10 > requested_precision)
|
|
3246
|
+
requested_precision = static_cast<unsigned>(d10);
|
|
3247
|
+
}
|
|
3248
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
|
|
3249
|
+
}
|
|
3250
|
+
else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
|
|
3251
|
+
{
|
|
3252
|
+
std::size_t d2 = used_gmp_int_bits(o);
|
|
3253
|
+
std::size_t d10 = 1 + multiprecision::detail::digits2_2_10(d2);
|
|
3254
|
+
if (d10 > requested_precision)
|
|
3255
|
+
this->precision(static_cast<unsigned>(d10));
|
|
3256
|
+
}
|
|
3257
|
+
mpf_set_z(this->data(), o.data());
|
|
3258
|
+
return *this;
|
|
3259
|
+
}
|
|
3260
|
+
inline gmp_float<0>& gmp_float<0>::operator=(const gmp_rational& o)
|
|
3261
|
+
{
|
|
3262
|
+
if (this->m_data[0]._mp_d == nullptr)
|
|
3263
|
+
{
|
|
3264
|
+
requested_precision = this->get_default_precision();
|
|
3265
|
+
if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
|
|
3266
|
+
{
|
|
3267
|
+
std::size_t d10 = 1 + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(o));
|
|
3268
|
+
if (d10 > requested_precision)
|
|
3269
|
+
requested_precision = static_cast<unsigned>(d10);
|
|
3270
|
+
}
|
|
3271
|
+
mpf_init2(this->m_data, multiprecision::detail::digits10_2_2(requested_precision));
|
|
3272
|
+
}
|
|
3273
|
+
else if (thread_default_variable_precision_options() >= variable_precision_options::preserve_all_precision)
|
|
3274
|
+
{
|
|
3275
|
+
std::size_t d10 = 1 + multiprecision::detail::digits2_2_10(used_gmp_rational_bits(o));
|
|
3276
|
+
if (d10 > requested_precision)
|
|
3277
|
+
this->precision(static_cast<unsigned>(d10));
|
|
3278
|
+
}
|
|
3279
|
+
mpf_set_q(this->data(), o.data());
|
|
3280
|
+
return *this;
|
|
3281
|
+
}
|
|
3282
|
+
inline gmp_int::gmp_int(const gmp_rational& o)
|
|
3283
|
+
{
|
|
3284
|
+
mpz_init(this->m_data);
|
|
3285
|
+
mpz_set_q(this->m_data, o.data());
|
|
3286
|
+
}
|
|
3287
|
+
inline gmp_int& gmp_int::operator=(const gmp_rational& o)
|
|
3288
|
+
{
|
|
3289
|
+
if (this->m_data[0]._mp_d == nullptr)
|
|
3290
|
+
mpz_init(this->m_data);
|
|
3291
|
+
mpz_set_q(this->m_data, o.data());
|
|
3292
|
+
return *this;
|
|
3293
|
+
}
|
|
3294
|
+
|
|
3295
|
+
} //namespace backends
|
|
3296
|
+
|
|
3297
|
+
template <expression_template_option ExpressionTemplates>
|
|
3298
|
+
struct component_type<number<gmp_rational, ExpressionTemplates> >
|
|
3299
|
+
{
|
|
3300
|
+
using type = number<gmp_int, ExpressionTemplates>;
|
|
3301
|
+
};
|
|
3302
|
+
|
|
3303
|
+
template <expression_template_option ET>
|
|
3304
|
+
inline number<gmp_int, ET> numerator(const number<gmp_rational, ET>& val)
|
|
3305
|
+
{
|
|
3306
|
+
number<gmp_int, ET> result;
|
|
3307
|
+
mpz_set(result.backend().data(), (mpq_numref(val.backend().data())));
|
|
3308
|
+
return result;
|
|
3309
|
+
}
|
|
3310
|
+
template <expression_template_option ET>
|
|
3311
|
+
inline number<gmp_int, ET> denominator(const number<gmp_rational, ET>& val)
|
|
3312
|
+
{
|
|
3313
|
+
number<gmp_int, ET> result;
|
|
3314
|
+
mpz_set(result.backend().data(), (mpq_denref(val.backend().data())));
|
|
3315
|
+
return result;
|
|
3316
|
+
}
|
|
3317
|
+
|
|
3318
|
+
namespace detail {
|
|
3319
|
+
|
|
3320
|
+
template <>
|
|
3321
|
+
struct digits2<number<gmp_float<0>, et_on> >
|
|
3322
|
+
{
|
|
3323
|
+
static long value()
|
|
3324
|
+
{
|
|
3325
|
+
return static_cast<long>(multiprecision::detail::digits10_2_2(gmp_float<0>::thread_default_precision()));
|
|
3326
|
+
}
|
|
3327
|
+
};
|
|
3328
|
+
|
|
3329
|
+
template <>
|
|
3330
|
+
struct digits2<number<gmp_float<0>, et_off> >
|
|
3331
|
+
{
|
|
3332
|
+
static long value()
|
|
3333
|
+
{
|
|
3334
|
+
return static_cast<long>(multiprecision::detail::digits10_2_2(gmp_float<0>::thread_default_precision()));
|
|
3335
|
+
}
|
|
3336
|
+
};
|
|
3337
|
+
|
|
3338
|
+
template <>
|
|
3339
|
+
struct digits2<number<debug_adaptor<gmp_float<0> >, et_on> >
|
|
3340
|
+
{
|
|
3341
|
+
static long value()
|
|
3342
|
+
{
|
|
3343
|
+
return static_cast<long>(multiprecision::detail::digits10_2_2(gmp_float<0>::thread_default_precision()));
|
|
3344
|
+
}
|
|
3345
|
+
};
|
|
3346
|
+
|
|
3347
|
+
template <>
|
|
3348
|
+
struct digits2<number<debug_adaptor<gmp_float<0> >, et_off> >
|
|
3349
|
+
{
|
|
3350
|
+
static long value()
|
|
3351
|
+
{
|
|
3352
|
+
return static_cast<long>(multiprecision::detail::digits10_2_2(gmp_float<0>::thread_default_precision()));
|
|
3353
|
+
}
|
|
3354
|
+
};
|
|
3355
|
+
|
|
3356
|
+
template <unsigned Digits10>
|
|
3357
|
+
struct transcendental_reduction_type<boost::multiprecision::backends::gmp_float<Digits10> >
|
|
3358
|
+
{
|
|
3359
|
+
//
|
|
3360
|
+
// The type used for trigonometric reduction needs 3 times the precision of the base type.
|
|
3361
|
+
// This is double the precision of the original type, plus the largest exponent supported.
|
|
3362
|
+
// As a practical measure the largest argument supported is 1/eps, as supporting larger
|
|
3363
|
+
// arguments requires the division of argument by PI/2 to also be done at higher precision,
|
|
3364
|
+
// otherwise the result (an integer) can not be represented exactly.
|
|
3365
|
+
//
|
|
3366
|
+
// See ARGUMENT REDUCTION FOR HUGE ARGUMENTS. K C Ng.
|
|
3367
|
+
//
|
|
3368
|
+
using type = boost::multiprecision::backends::gmp_float<Digits10 * 3>;
|
|
3369
|
+
};
|
|
3370
|
+
|
|
3371
|
+
|
|
3372
|
+
} // namespace detail
|
|
3373
|
+
|
|
3374
|
+
template <>
|
|
3375
|
+
struct number_category<detail::canonical<mpz_t, gmp_int>::type> : public std::integral_constant<int, number_kind_integer>
|
|
3376
|
+
{};
|
|
3377
|
+
template <>
|
|
3378
|
+
struct number_category<detail::canonical<mpq_t, gmp_rational>::type> : public std::integral_constant<int, number_kind_rational>
|
|
3379
|
+
{};
|
|
3380
|
+
template <>
|
|
3381
|
+
struct number_category<detail::canonical<mpf_t, gmp_float<0> >::type> : public std::integral_constant<int, number_kind_floating_point>
|
|
3382
|
+
{};
|
|
3383
|
+
|
|
3384
|
+
namespace detail {
|
|
3385
|
+
template <>
|
|
3386
|
+
struct is_variable_precision<backends::gmp_float<0> > : public std::integral_constant<bool, true>
|
|
3387
|
+
{};
|
|
3388
|
+
} // namespace detail
|
|
3389
|
+
|
|
3390
|
+
} // namespace multiprecision
|
|
3391
|
+
|
|
3392
|
+
namespace math { namespace tools {
|
|
3393
|
+
|
|
3394
|
+
#ifndef BOOST_MP_MATH_AVAILABLE
|
|
3395
|
+
|
|
3396
|
+
template <typename T>
|
|
3397
|
+
inline int digits();
|
|
3398
|
+
|
|
3399
|
+
template <typename T>
|
|
3400
|
+
inline T max_value();
|
|
3401
|
+
|
|
3402
|
+
template <typename T>
|
|
3403
|
+
inline T min_value();
|
|
3404
|
+
|
|
3405
|
+
#endif // BOOST_MP_MATH_AVAILABLE
|
|
3406
|
+
|
|
3407
|
+
inline void set_output_precision(const boost::multiprecision::mpf_float& val, std::ostream& os)
|
|
3408
|
+
{
|
|
3409
|
+
const int sz_prec = static_cast<int>(val.precision());
|
|
3410
|
+
|
|
3411
|
+
os << std::setprecision(sz_prec);
|
|
3412
|
+
}
|
|
3413
|
+
|
|
3414
|
+
template <>
|
|
3415
|
+
inline int digits<boost::multiprecision::mpf_float>()
|
|
3416
|
+
#ifdef BOOST_MATH_NOEXCEPT
|
|
3417
|
+
noexcept
|
|
3418
|
+
#endif
|
|
3419
|
+
{
|
|
3420
|
+
return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::mpf_float::thread_default_precision()));
|
|
3421
|
+
}
|
|
3422
|
+
template <>
|
|
3423
|
+
inline int digits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> >()
|
|
3424
|
+
#ifdef BOOST_MATH_NOEXCEPT
|
|
3425
|
+
noexcept
|
|
3426
|
+
#endif
|
|
3427
|
+
{
|
|
3428
|
+
return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::mpf_float::thread_default_precision()));
|
|
3429
|
+
}
|
|
3430
|
+
|
|
3431
|
+
template <>
|
|
3432
|
+
inline boost::multiprecision::mpf_float
|
|
3433
|
+
max_value<boost::multiprecision::mpf_float>()
|
|
3434
|
+
{
|
|
3435
|
+
boost::multiprecision::mpf_float result(0.5);
|
|
3436
|
+
mpf_mul_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
|
|
3437
|
+
return result;
|
|
3438
|
+
}
|
|
3439
|
+
|
|
3440
|
+
template <>
|
|
3441
|
+
inline boost::multiprecision::mpf_float
|
|
3442
|
+
min_value<boost::multiprecision::mpf_float>()
|
|
3443
|
+
{
|
|
3444
|
+
boost::multiprecision::mpf_float result(0.5);
|
|
3445
|
+
mpf_div_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
|
|
3446
|
+
return result;
|
|
3447
|
+
}
|
|
3448
|
+
|
|
3449
|
+
template <>
|
|
3450
|
+
inline boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off>
|
|
3451
|
+
max_value<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> >()
|
|
3452
|
+
{
|
|
3453
|
+
boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> result(0.5);
|
|
3454
|
+
mpf_mul_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
|
|
3455
|
+
return result;
|
|
3456
|
+
}
|
|
3457
|
+
|
|
3458
|
+
template <>
|
|
3459
|
+
inline boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off>
|
|
3460
|
+
min_value<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> >()
|
|
3461
|
+
{
|
|
3462
|
+
boost::multiprecision::number<boost::multiprecision::gmp_float<0>, boost::multiprecision::et_off> result(0.5);
|
|
3463
|
+
mpf_div_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
|
|
3464
|
+
return result;
|
|
3465
|
+
}
|
|
3466
|
+
|
|
3467
|
+
template <>
|
|
3468
|
+
inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> > >()
|
|
3469
|
+
#ifdef BOOST_MATH_NOEXCEPT
|
|
3470
|
+
noexcept
|
|
3471
|
+
#endif
|
|
3472
|
+
{
|
|
3473
|
+
return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> >::thread_default_precision()));
|
|
3474
|
+
}
|
|
3475
|
+
template <>
|
|
3476
|
+
inline int digits<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off> >()
|
|
3477
|
+
#ifdef BOOST_MATH_NOEXCEPT
|
|
3478
|
+
noexcept
|
|
3479
|
+
#endif
|
|
3480
|
+
{
|
|
3481
|
+
return static_cast<int>(multiprecision::detail::digits10_2_2(boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> >::thread_default_precision()));
|
|
3482
|
+
}
|
|
3483
|
+
|
|
3484
|
+
template <>
|
|
3485
|
+
inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> >
|
|
3486
|
+
max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> > >()
|
|
3487
|
+
{
|
|
3488
|
+
return max_value<boost::multiprecision::mpf_float>().backend();
|
|
3489
|
+
}
|
|
3490
|
+
|
|
3491
|
+
template <>
|
|
3492
|
+
inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> >
|
|
3493
|
+
min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpf_float::backend_type> > >()
|
|
3494
|
+
{
|
|
3495
|
+
return min_value<boost::multiprecision::mpf_float>().backend();
|
|
3496
|
+
}
|
|
3497
|
+
|
|
3498
|
+
template <>
|
|
3499
|
+
inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off>
|
|
3500
|
+
max_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off> >()
|
|
3501
|
+
{
|
|
3502
|
+
return max_value<boost::multiprecision::mpf_float>().backend();
|
|
3503
|
+
}
|
|
3504
|
+
|
|
3505
|
+
template <>
|
|
3506
|
+
inline boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off>
|
|
3507
|
+
min_value<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::gmp_float<0> >, boost::multiprecision::et_off> >()
|
|
3508
|
+
{
|
|
3509
|
+
return min_value<boost::multiprecision::mpf_float>().backend();
|
|
3510
|
+
}
|
|
3511
|
+
|
|
3512
|
+
}} // namespace math::tools
|
|
3513
|
+
|
|
3514
|
+
} // namespace boost
|
|
3515
|
+
|
|
3516
|
+
namespace std {
|
|
3517
|
+
|
|
3518
|
+
//
|
|
3519
|
+
// numeric_limits [partial] specializations for the types declared in this header:
|
|
3520
|
+
//
|
|
3521
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3522
|
+
class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >
|
|
3523
|
+
{
|
|
3524
|
+
using number_type = boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates>;
|
|
3525
|
+
|
|
3526
|
+
//
|
|
3527
|
+
// min and max values chosen so as to not cause segfaults when calling
|
|
3528
|
+
// mpf_get_str on 64-bit Linux builds. Possibly we could use larger
|
|
3529
|
+
// exponent values elsewhere.
|
|
3530
|
+
//
|
|
3531
|
+
static number_type calc_min()
|
|
3532
|
+
{
|
|
3533
|
+
number_type result(1);
|
|
3534
|
+
mpf_div_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
|
|
3535
|
+
return result;
|
|
3536
|
+
}
|
|
3537
|
+
static number_type calc_max()
|
|
3538
|
+
{
|
|
3539
|
+
number_type result(1);
|
|
3540
|
+
mpf_mul_2exp(result.backend().data(), result.backend().data(), (std::numeric_limits<mp_exp_t>::max)() / 64 + 1);
|
|
3541
|
+
return result;
|
|
3542
|
+
}
|
|
3543
|
+
static number_type calc_epsilon()
|
|
3544
|
+
{
|
|
3545
|
+
number_type result(1);
|
|
3546
|
+
mpf_div_2exp(result.backend().data(), result.backend().data(), std::numeric_limits<number_type>::digits - 1);
|
|
3547
|
+
return result;
|
|
3548
|
+
}
|
|
3549
|
+
|
|
3550
|
+
|
|
3551
|
+
public:
|
|
3552
|
+
static constexpr bool is_specialized = true;
|
|
3553
|
+
static number_type(min)()
|
|
3554
|
+
{
|
|
3555
|
+
// rely on C++11 thread safe initialization of statics:
|
|
3556
|
+
static const number_type value{calc_min()};
|
|
3557
|
+
return value;
|
|
3558
|
+
}
|
|
3559
|
+
static number_type(max)()
|
|
3560
|
+
{
|
|
3561
|
+
static number_type value{calc_max()};
|
|
3562
|
+
return value;
|
|
3563
|
+
}
|
|
3564
|
+
static constexpr number_type lowest()
|
|
3565
|
+
{
|
|
3566
|
+
return -(max)();
|
|
3567
|
+
}
|
|
3568
|
+
static constexpr int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301L ? 2 : 1));
|
|
3569
|
+
static constexpr int digits10 = Digits10;
|
|
3570
|
+
// Have to allow for a possible extra limb inside the gmp data structure:
|
|
3571
|
+
static constexpr int max_digits10 = Digits10 + 3 + ((GMP_LIMB_BITS * 301L) / 1000L);
|
|
3572
|
+
static constexpr bool is_signed = true;
|
|
3573
|
+
static constexpr bool is_integer = false;
|
|
3574
|
+
static constexpr bool is_exact = false;
|
|
3575
|
+
static constexpr int radix = 2;
|
|
3576
|
+
static number_type epsilon()
|
|
3577
|
+
{
|
|
3578
|
+
static const number_type value{calc_epsilon()};
|
|
3579
|
+
return value;
|
|
3580
|
+
}
|
|
3581
|
+
// What value should this be????
|
|
3582
|
+
static number_type round_error()
|
|
3583
|
+
{
|
|
3584
|
+
return 1;
|
|
3585
|
+
}
|
|
3586
|
+
static constexpr long min_exponent = LONG_MIN;
|
|
3587
|
+
static constexpr long min_exponent10 = (LONG_MIN / 1000) * 301L;
|
|
3588
|
+
static constexpr long max_exponent = LONG_MAX;
|
|
3589
|
+
static constexpr long max_exponent10 = (LONG_MAX / 1000) * 301L;
|
|
3590
|
+
static constexpr bool has_infinity = false;
|
|
3591
|
+
static constexpr bool has_quiet_NaN = false;
|
|
3592
|
+
static constexpr bool has_signaling_NaN = false;
|
|
3593
|
+
#ifdef _MSC_VER
|
|
3594
|
+
#pragma warning(push)
|
|
3595
|
+
#pragma warning(disable : 4996)
|
|
3596
|
+
#endif
|
|
3597
|
+
static constexpr float_denorm_style has_denorm = denorm_absent;
|
|
3598
|
+
#ifdef _MSC_VER
|
|
3599
|
+
#pragma warning(pop)
|
|
3600
|
+
#endif
|
|
3601
|
+
static constexpr bool has_denorm_loss = false;
|
|
3602
|
+
static constexpr number_type infinity() { return number_type(); }
|
|
3603
|
+
static constexpr number_type quiet_NaN() { return number_type(); }
|
|
3604
|
+
static constexpr number_type signaling_NaN() { return number_type(); }
|
|
3605
|
+
static constexpr number_type denorm_min() { return (min)(); }
|
|
3606
|
+
static constexpr bool is_iec559 = false;
|
|
3607
|
+
static constexpr bool is_bounded = true;
|
|
3608
|
+
static constexpr bool is_modulo = false;
|
|
3609
|
+
static constexpr bool traps = true;
|
|
3610
|
+
static constexpr bool tinyness_before = false;
|
|
3611
|
+
static constexpr float_round_style round_style = round_indeterminate;
|
|
3612
|
+
};
|
|
3613
|
+
|
|
3614
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3615
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::digits;
|
|
3616
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3617
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::digits10;
|
|
3618
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3619
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_digits10;
|
|
3620
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3621
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_signed;
|
|
3622
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3623
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_integer;
|
|
3624
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3625
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_exact;
|
|
3626
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3627
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::radix;
|
|
3628
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3629
|
+
constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::min_exponent;
|
|
3630
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3631
|
+
constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::min_exponent10;
|
|
3632
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3633
|
+
constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_exponent;
|
|
3634
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3635
|
+
constexpr long numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::max_exponent10;
|
|
3636
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3637
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_infinity;
|
|
3638
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3639
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_quiet_NaN;
|
|
3640
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3641
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_signaling_NaN;
|
|
3642
|
+
#ifdef _MSC_VER
|
|
3643
|
+
#pragma warning(push)
|
|
3644
|
+
#pragma warning(disable : 4996)
|
|
3645
|
+
#endif
|
|
3646
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3647
|
+
constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_denorm;
|
|
3648
|
+
#ifdef _MSC_VER
|
|
3649
|
+
#pragma warning(pop)
|
|
3650
|
+
#endif
|
|
3651
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3652
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::has_denorm_loss;
|
|
3653
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3654
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_iec559;
|
|
3655
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3656
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_bounded;
|
|
3657
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3658
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::is_modulo;
|
|
3659
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3660
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::traps;
|
|
3661
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3662
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::tinyness_before;
|
|
3663
|
+
template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3664
|
+
constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<Digits10>, ExpressionTemplates> >::round_style;
|
|
3665
|
+
|
|
3666
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3667
|
+
class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >
|
|
3668
|
+
{
|
|
3669
|
+
using number_type = boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates>;
|
|
3670
|
+
|
|
3671
|
+
public:
|
|
3672
|
+
static constexpr bool is_specialized = false;
|
|
3673
|
+
static number_type(min)() { return number_type(); }
|
|
3674
|
+
static number_type(max)() { return number_type(); }
|
|
3675
|
+
static number_type lowest() { return number_type(); }
|
|
3676
|
+
static constexpr int digits = 0;
|
|
3677
|
+
static constexpr int digits10 = 0;
|
|
3678
|
+
static constexpr int max_digits10 = 0;
|
|
3679
|
+
static constexpr bool is_signed = false;
|
|
3680
|
+
static constexpr bool is_integer = false;
|
|
3681
|
+
static constexpr bool is_exact = false;
|
|
3682
|
+
static constexpr int radix = 0;
|
|
3683
|
+
static number_type epsilon() { return number_type(); }
|
|
3684
|
+
static number_type round_error() { return number_type(); }
|
|
3685
|
+
static constexpr int min_exponent = 0;
|
|
3686
|
+
static constexpr int min_exponent10 = 0;
|
|
3687
|
+
static constexpr int max_exponent = 0;
|
|
3688
|
+
static constexpr int max_exponent10 = 0;
|
|
3689
|
+
static constexpr bool has_infinity = false;
|
|
3690
|
+
static constexpr bool has_quiet_NaN = false;
|
|
3691
|
+
static constexpr bool has_signaling_NaN = false;
|
|
3692
|
+
#ifdef _MSC_VER
|
|
3693
|
+
#pragma warning(push)
|
|
3694
|
+
#pragma warning(disable : 4996)
|
|
3695
|
+
#endif
|
|
3696
|
+
static constexpr float_denorm_style has_denorm = denorm_absent;
|
|
3697
|
+
#ifdef _MSC_VER
|
|
3698
|
+
#pragma warning(pop)
|
|
3699
|
+
#endif
|
|
3700
|
+
static constexpr bool has_denorm_loss = false;
|
|
3701
|
+
static number_type infinity() { return number_type(); }
|
|
3702
|
+
static number_type quiet_NaN() { return number_type(); }
|
|
3703
|
+
static number_type signaling_NaN() { return number_type(); }
|
|
3704
|
+
static number_type denorm_min() { return number_type(); }
|
|
3705
|
+
static constexpr bool is_iec559 = false;
|
|
3706
|
+
static constexpr bool is_bounded = false;
|
|
3707
|
+
static constexpr bool is_modulo = false;
|
|
3708
|
+
static constexpr bool traps = false;
|
|
3709
|
+
static constexpr bool tinyness_before = false;
|
|
3710
|
+
static constexpr float_round_style round_style = round_indeterminate;
|
|
3711
|
+
};
|
|
3712
|
+
|
|
3713
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3714
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::digits;
|
|
3715
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3716
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::digits10;
|
|
3717
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3718
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_digits10;
|
|
3719
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3720
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_signed;
|
|
3721
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3722
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_integer;
|
|
3723
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3724
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_exact;
|
|
3725
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3726
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::radix;
|
|
3727
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3728
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::min_exponent;
|
|
3729
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3730
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::min_exponent10;
|
|
3731
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3732
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_exponent;
|
|
3733
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3734
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::max_exponent10;
|
|
3735
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3736
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_infinity;
|
|
3737
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3738
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_quiet_NaN;
|
|
3739
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3740
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_signaling_NaN;
|
|
3741
|
+
#ifdef _MSC_VER
|
|
3742
|
+
#pragma warning(push)
|
|
3743
|
+
#pragma warning(disable : 4996)
|
|
3744
|
+
#endif
|
|
3745
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3746
|
+
constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_denorm;
|
|
3747
|
+
#ifdef _MSC_VER
|
|
3748
|
+
#pragma warning(pop)
|
|
3749
|
+
#endif
|
|
3750
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3751
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::has_denorm_loss;
|
|
3752
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3753
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_iec559;
|
|
3754
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3755
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_bounded;
|
|
3756
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3757
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::is_modulo;
|
|
3758
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3759
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::traps;
|
|
3760
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3761
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::tinyness_before;
|
|
3762
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3763
|
+
constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >::round_style;
|
|
3764
|
+
|
|
3765
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3766
|
+
class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >
|
|
3767
|
+
{
|
|
3768
|
+
using number_type = boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates>;
|
|
3769
|
+
|
|
3770
|
+
public:
|
|
3771
|
+
static constexpr bool is_specialized = true;
|
|
3772
|
+
//
|
|
3773
|
+
// Largest and smallest numbers are bounded only by available memory, set
|
|
3774
|
+
// to zero:
|
|
3775
|
+
//
|
|
3776
|
+
static number_type(min)()
|
|
3777
|
+
{
|
|
3778
|
+
return number_type();
|
|
3779
|
+
}
|
|
3780
|
+
static number_type(max)()
|
|
3781
|
+
{
|
|
3782
|
+
return number_type();
|
|
3783
|
+
}
|
|
3784
|
+
static number_type lowest() { return (min)(); }
|
|
3785
|
+
static constexpr int digits = INT_MAX;
|
|
3786
|
+
static constexpr int digits10 = (INT_MAX / 1000) * 301L;
|
|
3787
|
+
static constexpr int max_digits10 = digits10 + 3;
|
|
3788
|
+
static constexpr bool is_signed = true;
|
|
3789
|
+
static constexpr bool is_integer = true;
|
|
3790
|
+
static constexpr bool is_exact = true;
|
|
3791
|
+
static constexpr int radix = 2;
|
|
3792
|
+
static number_type epsilon() { return number_type(); }
|
|
3793
|
+
static number_type round_error() { return number_type(); }
|
|
3794
|
+
static constexpr int min_exponent = 0;
|
|
3795
|
+
static constexpr int min_exponent10 = 0;
|
|
3796
|
+
static constexpr int max_exponent = 0;
|
|
3797
|
+
static constexpr int max_exponent10 = 0;
|
|
3798
|
+
static constexpr bool has_infinity = false;
|
|
3799
|
+
static constexpr bool has_quiet_NaN = false;
|
|
3800
|
+
static constexpr bool has_signaling_NaN = false;
|
|
3801
|
+
#ifdef _MSC_VER
|
|
3802
|
+
#pragma warning(push)
|
|
3803
|
+
#pragma warning(disable : 4996)
|
|
3804
|
+
#endif
|
|
3805
|
+
static constexpr float_denorm_style has_denorm = denorm_absent;
|
|
3806
|
+
#ifdef _MSC_VER
|
|
3807
|
+
#pragma warning(pop)
|
|
3808
|
+
#endif
|
|
3809
|
+
static constexpr bool has_denorm_loss = false;
|
|
3810
|
+
static number_type infinity() { return number_type(); }
|
|
3811
|
+
static number_type quiet_NaN() { return number_type(); }
|
|
3812
|
+
static number_type signaling_NaN() { return number_type(); }
|
|
3813
|
+
static number_type denorm_min() { return number_type(); }
|
|
3814
|
+
static constexpr bool is_iec559 = false;
|
|
3815
|
+
static constexpr bool is_bounded = false;
|
|
3816
|
+
static constexpr bool is_modulo = false;
|
|
3817
|
+
static constexpr bool traps = false;
|
|
3818
|
+
static constexpr bool tinyness_before = false;
|
|
3819
|
+
static constexpr float_round_style round_style = round_toward_zero;
|
|
3820
|
+
};
|
|
3821
|
+
|
|
3822
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3823
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::digits;
|
|
3824
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3825
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::digits10;
|
|
3826
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3827
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_digits10;
|
|
3828
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3829
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_signed;
|
|
3830
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3831
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_integer;
|
|
3832
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3833
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_exact;
|
|
3834
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3835
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::radix;
|
|
3836
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3837
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::min_exponent;
|
|
3838
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3839
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::min_exponent10;
|
|
3840
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3841
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_exponent;
|
|
3842
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3843
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::max_exponent10;
|
|
3844
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3845
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_infinity;
|
|
3846
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3847
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_quiet_NaN;
|
|
3848
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3849
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_signaling_NaN;
|
|
3850
|
+
#ifdef _MSC_VER
|
|
3851
|
+
#pragma warning(push)
|
|
3852
|
+
#pragma warning(disable : 4996)
|
|
3853
|
+
#endif
|
|
3854
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3855
|
+
constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_denorm;
|
|
3856
|
+
#ifdef _MSC_VER
|
|
3857
|
+
#pragma warning(pop)
|
|
3858
|
+
#endif
|
|
3859
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3860
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::has_denorm_loss;
|
|
3861
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3862
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_iec559;
|
|
3863
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3864
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_bounded;
|
|
3865
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3866
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::is_modulo;
|
|
3867
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3868
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::traps;
|
|
3869
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3870
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::tinyness_before;
|
|
3871
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3872
|
+
constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_int, ExpressionTemplates> >::round_style;
|
|
3873
|
+
|
|
3874
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3875
|
+
class numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >
|
|
3876
|
+
{
|
|
3877
|
+
using number_type = boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates>;
|
|
3878
|
+
|
|
3879
|
+
public:
|
|
3880
|
+
static constexpr bool is_specialized = true;
|
|
3881
|
+
//
|
|
3882
|
+
// Largest and smallest numbers are bounded only by available memory, set
|
|
3883
|
+
// to zero:
|
|
3884
|
+
//
|
|
3885
|
+
static number_type(min)()
|
|
3886
|
+
{
|
|
3887
|
+
return number_type();
|
|
3888
|
+
}
|
|
3889
|
+
static number_type(max)()
|
|
3890
|
+
{
|
|
3891
|
+
return number_type();
|
|
3892
|
+
}
|
|
3893
|
+
static number_type lowest() { return (min)(); }
|
|
3894
|
+
// Digits are unbounded, use zero for now:
|
|
3895
|
+
static constexpr int digits = INT_MAX;
|
|
3896
|
+
static constexpr int digits10 = (INT_MAX / 1000) * 301L;
|
|
3897
|
+
static constexpr int max_digits10 = digits10 + 3;
|
|
3898
|
+
static constexpr bool is_signed = true;
|
|
3899
|
+
static constexpr bool is_integer = false;
|
|
3900
|
+
static constexpr bool is_exact = true;
|
|
3901
|
+
static constexpr int radix = 2;
|
|
3902
|
+
static number_type epsilon() { return number_type(); }
|
|
3903
|
+
static number_type round_error() { return number_type(); }
|
|
3904
|
+
static constexpr int min_exponent = 0;
|
|
3905
|
+
static constexpr int min_exponent10 = 0;
|
|
3906
|
+
static constexpr int max_exponent = 0;
|
|
3907
|
+
static constexpr int max_exponent10 = 0;
|
|
3908
|
+
static constexpr bool has_infinity = false;
|
|
3909
|
+
static constexpr bool has_quiet_NaN = false;
|
|
3910
|
+
static constexpr bool has_signaling_NaN = false;
|
|
3911
|
+
#ifdef _MSC_VER
|
|
3912
|
+
#pragma warning(push)
|
|
3913
|
+
#pragma warning(disable : 4996)
|
|
3914
|
+
#endif
|
|
3915
|
+
static constexpr float_denorm_style has_denorm = denorm_absent;
|
|
3916
|
+
#ifdef _MSC_VER
|
|
3917
|
+
#pragma warning(pop)
|
|
3918
|
+
#endif
|
|
3919
|
+
static constexpr bool has_denorm_loss = false;
|
|
3920
|
+
static number_type infinity() { return number_type(); }
|
|
3921
|
+
static number_type quiet_NaN() { return number_type(); }
|
|
3922
|
+
static number_type signaling_NaN() { return number_type(); }
|
|
3923
|
+
static number_type denorm_min() { return (min)(); }
|
|
3924
|
+
static constexpr bool is_iec559 = false;
|
|
3925
|
+
static constexpr bool is_bounded = false;
|
|
3926
|
+
static constexpr bool is_modulo = false;
|
|
3927
|
+
static constexpr bool traps = false;
|
|
3928
|
+
static constexpr bool tinyness_before = false;
|
|
3929
|
+
static constexpr float_round_style round_style = round_toward_zero;
|
|
3930
|
+
};
|
|
3931
|
+
|
|
3932
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3933
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::digits;
|
|
3934
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3935
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::digits10;
|
|
3936
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3937
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_digits10;
|
|
3938
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3939
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_signed;
|
|
3940
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3941
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_integer;
|
|
3942
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3943
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_exact;
|
|
3944
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3945
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::radix;
|
|
3946
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3947
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::min_exponent;
|
|
3948
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3949
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::min_exponent10;
|
|
3950
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3951
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_exponent;
|
|
3952
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3953
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::max_exponent10;
|
|
3954
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3955
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_infinity;
|
|
3956
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3957
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_quiet_NaN;
|
|
3958
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3959
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_signaling_NaN;
|
|
3960
|
+
#ifdef _MSC_VER
|
|
3961
|
+
#pragma warning(push)
|
|
3962
|
+
#pragma warning(disable : 4996)
|
|
3963
|
+
#endif
|
|
3964
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3965
|
+
constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_denorm;
|
|
3966
|
+
#ifdef _MSC_VER
|
|
3967
|
+
#pragma warning(pop)
|
|
3968
|
+
#endif
|
|
3969
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3970
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::has_denorm_loss;
|
|
3971
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3972
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_iec559;
|
|
3973
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3974
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_bounded;
|
|
3975
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3976
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::is_modulo;
|
|
3977
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3978
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::traps;
|
|
3979
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3980
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::tinyness_before;
|
|
3981
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3982
|
+
constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::gmp_rational, ExpressionTemplates> >::round_style;
|
|
3983
|
+
|
|
3984
|
+
#ifdef BOOST_MSVC
|
|
3985
|
+
#pragma warning(pop)
|
|
3986
|
+
#endif
|
|
3987
|
+
|
|
3988
|
+
} // namespace std
|
|
3989
|
+
|
|
3990
|
+
namespace Eigen
|
|
3991
|
+
{
|
|
3992
|
+
|
|
3993
|
+
template <class B1, class B2>
|
|
3994
|
+
struct NumTraitsImp;
|
|
3995
|
+
|
|
3996
|
+
template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3997
|
+
struct NumTraitsImp<boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates>, boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates> >
|
|
3998
|
+
{
|
|
3999
|
+
using self_type = boost::multiprecision::number<boost::multiprecision::gmp_float<0>, ExpressionTemplates>;
|
|
4000
|
+
using Real = typename boost::multiprecision::scalar_result_from_possible_complex<self_type>::type;
|
|
4001
|
+
using NonInteger = self_type; // Not correct but we can't do much better??
|
|
4002
|
+
using Literal = double;
|
|
4003
|
+
using Nested = self_type;
|
|
4004
|
+
enum
|
|
4005
|
+
{
|
|
4006
|
+
IsComplex = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_complex,
|
|
4007
|
+
IsInteger = boost::multiprecision::number_category<self_type>::value == boost::multiprecision::number_kind_integer,
|
|
4008
|
+
ReadCost = 1,
|
|
4009
|
+
AddCost = 4,
|
|
4010
|
+
MulCost = 8,
|
|
4011
|
+
IsSigned = std::numeric_limits<self_type>::is_specialized ? std::numeric_limits<self_type>::is_signed : true,
|
|
4012
|
+
RequireInitialization = 1,
|
|
4013
|
+
};
|
|
4014
|
+
|
|
4015
|
+
static Real highest() noexcept
|
|
4016
|
+
{
|
|
4017
|
+
return boost::math::tools::max_value<Real>();
|
|
4018
|
+
}
|
|
4019
|
+
static Real lowest() noexcept
|
|
4020
|
+
{
|
|
4021
|
+
return boost::math::tools::min_value<Real>();
|
|
4022
|
+
}
|
|
4023
|
+
static int digits() noexcept
|
|
4024
|
+
{
|
|
4025
|
+
return boost::math::tools::digits<Real>();
|
|
4026
|
+
}
|
|
4027
|
+
static int digits10()
|
|
4028
|
+
{
|
|
4029
|
+
return Real::thread_default_precision();
|
|
4030
|
+
}
|
|
4031
|
+
static Real epsilon()
|
|
4032
|
+
{
|
|
4033
|
+
return ldexp(Real(1), 1 - digits());
|
|
4034
|
+
}
|
|
4035
|
+
static Real dummy_precision()
|
|
4036
|
+
{
|
|
4037
|
+
return 1000 * epsilon();
|
|
4038
|
+
}
|
|
4039
|
+
static constexpr long min_exponent() noexcept
|
|
4040
|
+
{
|
|
4041
|
+
return LONG_MIN;
|
|
4042
|
+
}
|
|
4043
|
+
static constexpr long max_exponent() noexcept
|
|
4044
|
+
{
|
|
4045
|
+
return LONG_MAX;
|
|
4046
|
+
}
|
|
4047
|
+
static Real infinity()
|
|
4048
|
+
{
|
|
4049
|
+
return Real();
|
|
4050
|
+
}
|
|
4051
|
+
static Real quiet_NaN()
|
|
4052
|
+
{
|
|
4053
|
+
return Real();
|
|
4054
|
+
}
|
|
4055
|
+
};
|
|
4056
|
+
|
|
4057
|
+
}
|
|
4058
|
+
|
|
4059
|
+
|
|
4060
|
+
#endif
|