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,3690 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright Christopher Kormanyos 2002 - 2021.
|
|
3
|
+
// Copyright 2011 -2021 John Maddock. 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
|
+
// This work is based on an earlier work:
|
|
8
|
+
// "Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations",
|
|
9
|
+
// in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011. http://doi.acm.org/10.1145/1916461.1916469
|
|
10
|
+
//
|
|
11
|
+
// There are some "noexcept" specifications on the functions in this file.
|
|
12
|
+
// Unlike in pre-C++11 versions, compilers can now detect noexcept misuse
|
|
13
|
+
// at compile time, allowing for simple use of it here.
|
|
14
|
+
//
|
|
15
|
+
|
|
16
|
+
#ifndef BOOST_MP_CPP_DEC_FLOAT_HPP
|
|
17
|
+
#define BOOST_MP_CPP_DEC_FLOAT_HPP
|
|
18
|
+
|
|
19
|
+
#include <cmath>
|
|
20
|
+
#include <cstdint>
|
|
21
|
+
#include <cstdlib>
|
|
22
|
+
#include <algorithm>
|
|
23
|
+
#include <array>
|
|
24
|
+
#include <initializer_list>
|
|
25
|
+
#include <iomanip>
|
|
26
|
+
#include <string>
|
|
27
|
+
#include <limits>
|
|
28
|
+
#include <stdexcept>
|
|
29
|
+
#include <sstream>
|
|
30
|
+
#include <locale>
|
|
31
|
+
#include <ios>
|
|
32
|
+
#include <boost/multiprecision/detail/standalone_config.hpp>
|
|
33
|
+
#include <boost/multiprecision/number.hpp>
|
|
34
|
+
#include <boost/multiprecision/detail/fpclassify.hpp>
|
|
35
|
+
#include <boost/multiprecision/detail/dynamic_array.hpp>
|
|
36
|
+
#include <boost/multiprecision/detail/hash.hpp>
|
|
37
|
+
#include <boost/multiprecision/detail/float128_functions.hpp>
|
|
38
|
+
#include <boost/multiprecision/detail/itos.hpp>
|
|
39
|
+
#include <boost/multiprecision/detail/static_array.hpp>
|
|
40
|
+
#include <boost/multiprecision/detail/tables.hpp>
|
|
41
|
+
#include <boost/multiprecision/detail/no_exceptions_support.hpp>
|
|
42
|
+
#include <boost/multiprecision/detail/assert.hpp>
|
|
43
|
+
|
|
44
|
+
#ifdef BOOST_MP_MATH_AVAILABLE
|
|
45
|
+
//
|
|
46
|
+
// Headers required for Boost.Math integration:
|
|
47
|
+
//
|
|
48
|
+
#include <boost/math/policies/policy.hpp>
|
|
49
|
+
//
|
|
50
|
+
// Some includes we need from Boost.Math, since we rely on that library to provide these functions:
|
|
51
|
+
//
|
|
52
|
+
#include <boost/math/special_functions/acosh.hpp>
|
|
53
|
+
#include <boost/math/special_functions/asinh.hpp>
|
|
54
|
+
#include <boost/math/special_functions/atanh.hpp>
|
|
55
|
+
#include <boost/math/special_functions/cbrt.hpp>
|
|
56
|
+
#include <boost/math/special_functions/expm1.hpp>
|
|
57
|
+
#include <boost/math/special_functions/gamma.hpp>
|
|
58
|
+
#endif
|
|
59
|
+
|
|
60
|
+
#ifdef BOOST_MSVC
|
|
61
|
+
#pragma warning(push)
|
|
62
|
+
#pragma warning(disable : 6326) // comparison of two constants
|
|
63
|
+
#endif
|
|
64
|
+
|
|
65
|
+
namespace boost {
|
|
66
|
+
namespace multiprecision {
|
|
67
|
+
|
|
68
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
69
|
+
struct number_category<backends::cpp_dec_float<Digits10, ExponentType, Allocator> > : public std::integral_constant<int, number_kind_floating_point>
|
|
70
|
+
{};
|
|
71
|
+
|
|
72
|
+
namespace backends {
|
|
73
|
+
|
|
74
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
75
|
+
class cpp_dec_float
|
|
76
|
+
{
|
|
77
|
+
private:
|
|
78
|
+
// Perform some static sanity checks.
|
|
79
|
+
static_assert(boost::multiprecision::detail::is_signed<ExponentType>::value,
|
|
80
|
+
"ExponentType must be a signed built in integer type.");
|
|
81
|
+
|
|
82
|
+
static_assert(sizeof(ExponentType) > 1,
|
|
83
|
+
"ExponentType is too small.");
|
|
84
|
+
|
|
85
|
+
static_assert(Digits10 < UINT32_C(0x80000000),
|
|
86
|
+
"Digits10 exceeds the maximum.");
|
|
87
|
+
|
|
88
|
+
// Private class-local constants.
|
|
89
|
+
static constexpr std::int32_t cpp_dec_float_digits10_limit_lo = INT32_C(9);
|
|
90
|
+
static constexpr std::int32_t cpp_dec_float_digits10_limit_hi = static_cast<std::int32_t>((std::numeric_limits<std::int32_t>::max)() - 100);
|
|
91
|
+
|
|
92
|
+
static constexpr std::int32_t cpp_dec_float_elem_digits10 = INT32_C(8);
|
|
93
|
+
static constexpr std::int32_t cpp_dec_float_elem_mask = INT32_C(100000000);
|
|
94
|
+
|
|
95
|
+
static constexpr std::int32_t cpp_dec_float_elems_for_kara = static_cast<std::int32_t>(128 + 1);
|
|
96
|
+
|
|
97
|
+
public:
|
|
98
|
+
using signed_types = std::tuple<long long> ;
|
|
99
|
+
using unsigned_types = std::tuple<unsigned long long>;
|
|
100
|
+
using float_types = std::tuple<double, long double>;
|
|
101
|
+
using exponent_type = ExponentType;
|
|
102
|
+
|
|
103
|
+
// Public class-local constants.
|
|
104
|
+
static constexpr std::int32_t cpp_dec_float_radix = INT32_C(10);
|
|
105
|
+
static constexpr std::int32_t cpp_dec_float_digits10 = ((static_cast<std::int32_t>(Digits10) < cpp_dec_float_digits10_limit_lo) ? cpp_dec_float_digits10_limit_lo : ((static_cast<std::int32_t>(Digits10) > cpp_dec_float_digits10_limit_hi) ? cpp_dec_float_digits10_limit_hi : static_cast<std::int32_t>(Digits10)));
|
|
106
|
+
static constexpr exponent_type cpp_dec_float_max_exp10 = (static_cast<exponent_type>(1) << (std::numeric_limits<exponent_type>::digits - 5));
|
|
107
|
+
static constexpr exponent_type cpp_dec_float_min_exp10 = -cpp_dec_float_max_exp10;
|
|
108
|
+
static constexpr exponent_type cpp_dec_float_max_exp = cpp_dec_float_max_exp10;
|
|
109
|
+
static constexpr exponent_type cpp_dec_float_min_exp = cpp_dec_float_min_exp10;
|
|
110
|
+
|
|
111
|
+
static_assert(cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_exp10 == -cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp10, "Failed exponent range check");
|
|
112
|
+
|
|
113
|
+
static_assert(0 == cpp_dec_float_max_exp10 % cpp_dec_float_elem_digits10, "Failed digit sanity check");
|
|
114
|
+
|
|
115
|
+
private:
|
|
116
|
+
// There are three guard limbs.
|
|
117
|
+
// 1) The first limb has 'play' from 1...8 decimal digits.
|
|
118
|
+
// 2) The last limb also has 'play' from 1...8 decimal digits.
|
|
119
|
+
// 3) One limb can get lost when justifying after multiply.
|
|
120
|
+
static constexpr std::int32_t cpp_dec_float_elem_number = static_cast<std::int32_t>(((Digits10 / cpp_dec_float_elem_digits10) + (((Digits10 % cpp_dec_float_elem_digits10) != 0) ? 1 : 0)) + 3);
|
|
121
|
+
|
|
122
|
+
public:
|
|
123
|
+
static constexpr std::int32_t cpp_dec_float_max_digits10 = static_cast<std::int32_t>(cpp_dec_float_elem_number * cpp_dec_float_elem_digits10);
|
|
124
|
+
|
|
125
|
+
private:
|
|
126
|
+
using array_type =
|
|
127
|
+
typename std::conditional<std::is_void<Allocator>::value,
|
|
128
|
+
detail::static_array <std::uint32_t, static_cast<std::uint32_t>(cpp_dec_float_elem_number)>,
|
|
129
|
+
detail::dynamic_array<std::uint32_t, static_cast<std::uint32_t>(cpp_dec_float_elem_number), Allocator> >::type;
|
|
130
|
+
|
|
131
|
+
typedef enum enum_fpclass_type
|
|
132
|
+
{
|
|
133
|
+
cpp_dec_float_finite,
|
|
134
|
+
cpp_dec_float_inf,
|
|
135
|
+
cpp_dec_float_NaN
|
|
136
|
+
} fpclass_type;
|
|
137
|
+
|
|
138
|
+
array_type data;
|
|
139
|
+
exponent_type exp;
|
|
140
|
+
bool neg;
|
|
141
|
+
fpclass_type fpclass;
|
|
142
|
+
std::int32_t prec_elem;
|
|
143
|
+
|
|
144
|
+
// Private constructor from the floating-point class type.
|
|
145
|
+
explicit cpp_dec_float(fpclass_type c) : data(),
|
|
146
|
+
exp(static_cast<exponent_type>(0)),
|
|
147
|
+
neg(false),
|
|
148
|
+
fpclass(c),
|
|
149
|
+
prec_elem(cpp_dec_float_elem_number) {}
|
|
150
|
+
|
|
151
|
+
// Constructor from an initializer_list, an optional
|
|
152
|
+
// (value-aligned) exponent and a Boolean sign.
|
|
153
|
+
static cpp_dec_float from_lst(std::initializer_list<std::uint32_t> lst,
|
|
154
|
+
const exponent_type e = 0,
|
|
155
|
+
const bool n = false)
|
|
156
|
+
{
|
|
157
|
+
cpp_dec_float a;
|
|
158
|
+
|
|
159
|
+
a.data = array_type(lst);
|
|
160
|
+
a.exp = e;
|
|
161
|
+
a.neg = n;
|
|
162
|
+
a.fpclass = cpp_dec_float_finite;
|
|
163
|
+
a.prec_elem = cpp_dec_float_elem_number;
|
|
164
|
+
|
|
165
|
+
return a;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
public:
|
|
169
|
+
// Public Constructors
|
|
170
|
+
cpp_dec_float() noexcept(noexcept(array_type())) : data(),
|
|
171
|
+
exp(static_cast<exponent_type>(0)),
|
|
172
|
+
neg(false),
|
|
173
|
+
fpclass(cpp_dec_float_finite),
|
|
174
|
+
prec_elem(cpp_dec_float_elem_number) {}
|
|
175
|
+
|
|
176
|
+
cpp_dec_float(const char* s) : data(),
|
|
177
|
+
exp(static_cast<exponent_type>(0)),
|
|
178
|
+
neg(false),
|
|
179
|
+
fpclass(cpp_dec_float_finite),
|
|
180
|
+
prec_elem(cpp_dec_float_elem_number)
|
|
181
|
+
{
|
|
182
|
+
*this = s;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
template <class I>
|
|
186
|
+
cpp_dec_float(I i,
|
|
187
|
+
typename std::enable_if<boost::multiprecision::detail::is_unsigned<I>::value && (sizeof(I) <= sizeof(long long))>::type* = nullptr)
|
|
188
|
+
: data(),
|
|
189
|
+
exp(static_cast<exponent_type>(0)),
|
|
190
|
+
neg(false),
|
|
191
|
+
fpclass(cpp_dec_float_finite),
|
|
192
|
+
prec_elem(cpp_dec_float_elem_number)
|
|
193
|
+
{
|
|
194
|
+
from_unsigned_long_long(i);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
template <class I>
|
|
198
|
+
cpp_dec_float(I i,
|
|
199
|
+
typename std::enable_if<( boost::multiprecision::detail::is_signed<I>::value
|
|
200
|
+
&& boost::multiprecision::detail::is_integral<I>::value
|
|
201
|
+
&& (sizeof(I) <= sizeof(long long)))>::type* = nullptr)
|
|
202
|
+
: data(),
|
|
203
|
+
exp(static_cast<exponent_type>(0)),
|
|
204
|
+
neg(false),
|
|
205
|
+
fpclass(cpp_dec_float_finite),
|
|
206
|
+
prec_elem(cpp_dec_float_elem_number)
|
|
207
|
+
{
|
|
208
|
+
if (i < 0)
|
|
209
|
+
{
|
|
210
|
+
from_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(i));
|
|
211
|
+
negate();
|
|
212
|
+
}
|
|
213
|
+
else
|
|
214
|
+
from_unsigned_long_long(static_cast<unsigned long long>(i));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
cpp_dec_float(const cpp_dec_float& f) noexcept(noexcept(array_type(std::declval<const array_type&>())))
|
|
218
|
+
: data(f.data),
|
|
219
|
+
exp(f.exp),
|
|
220
|
+
neg(f.neg),
|
|
221
|
+
fpclass(f.fpclass),
|
|
222
|
+
prec_elem(f.prec_elem) {}
|
|
223
|
+
|
|
224
|
+
template <unsigned D, class ET, class A>
|
|
225
|
+
cpp_dec_float(const cpp_dec_float<D, ET, A>& f, typename std::enable_if<D <= Digits10>::type* = nullptr)
|
|
226
|
+
: data(),
|
|
227
|
+
exp(f.exp),
|
|
228
|
+
neg(f.neg),
|
|
229
|
+
fpclass(static_cast<fpclass_type>(static_cast<int>(f.fpclass))),
|
|
230
|
+
prec_elem(cpp_dec_float_elem_number)
|
|
231
|
+
{
|
|
232
|
+
std::copy(f.data.begin(), f.data.begin() + f.prec_elem, data.begin());
|
|
233
|
+
}
|
|
234
|
+
template <unsigned D, class ET, class A>
|
|
235
|
+
explicit cpp_dec_float(const cpp_dec_float<D, ET, A>& f, typename std::enable_if< !(D <= Digits10)>::type* = nullptr)
|
|
236
|
+
: data(),
|
|
237
|
+
exp(f.exp),
|
|
238
|
+
neg(f.neg),
|
|
239
|
+
fpclass(static_cast<fpclass_type>(static_cast<int>(f.fpclass))),
|
|
240
|
+
prec_elem(cpp_dec_float_elem_number)
|
|
241
|
+
{
|
|
242
|
+
// TODO: this doesn't round!
|
|
243
|
+
std::copy(f.data.begin(), f.data.begin() + prec_elem, data.begin());
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
template <class F>
|
|
247
|
+
cpp_dec_float(const F val, typename std::enable_if<std::is_floating_point<F>::value
|
|
248
|
+
>::type* = nullptr) : data(),
|
|
249
|
+
exp(static_cast<exponent_type>(0)),
|
|
250
|
+
neg(false),
|
|
251
|
+
fpclass(cpp_dec_float_finite),
|
|
252
|
+
prec_elem(cpp_dec_float_elem_number)
|
|
253
|
+
{
|
|
254
|
+
*this = val;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
cpp_dec_float(const double mantissa, const exponent_type exponent);
|
|
258
|
+
|
|
259
|
+
std::size_t hash() const
|
|
260
|
+
{
|
|
261
|
+
std::size_t result = 0;
|
|
262
|
+
for (int i = 0; i < prec_elem; ++i)
|
|
263
|
+
boost::multiprecision::detail::hash_combine(result, data[i]);
|
|
264
|
+
boost::multiprecision::detail::hash_combine(result, exp, neg, static_cast<std::size_t>(fpclass));
|
|
265
|
+
return result;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Specific special values.
|
|
269
|
+
static const cpp_dec_float& nan () { static const cpp_dec_float val(cpp_dec_float_NaN); return val; }
|
|
270
|
+
static const cpp_dec_float& inf () { static const cpp_dec_float val(cpp_dec_float_inf); return val; }
|
|
271
|
+
static const cpp_dec_float& (max)() { static const cpp_dec_float val(from_lst({ std::uint32_t(1u) }, cpp_dec_float_max_exp10)); return val; }
|
|
272
|
+
static const cpp_dec_float& (min)() { static const cpp_dec_float val(from_lst({ std::uint32_t(1u) }, cpp_dec_float_min_exp10)); return val; }
|
|
273
|
+
static const cpp_dec_float& zero() { static const cpp_dec_float val(from_lst({ std::uint32_t(0u) })); return val; }
|
|
274
|
+
static const cpp_dec_float& one () { static const cpp_dec_float val(from_lst({ std::uint32_t(1u) })); return val; }
|
|
275
|
+
static const cpp_dec_float& two () { static const cpp_dec_float val(from_lst({ std::uint32_t(2u) })); return val; }
|
|
276
|
+
static const cpp_dec_float& half() { static const cpp_dec_float val(from_lst({ std::uint32_t(cpp_dec_float_elem_mask / 2)}, -8)); return val; }
|
|
277
|
+
|
|
278
|
+
static const cpp_dec_float& double_min() { static const cpp_dec_float val((std::numeric_limits<double>::min)()); return val; }
|
|
279
|
+
static const cpp_dec_float& double_max() { static const cpp_dec_float val((std::numeric_limits<double>::max)()); return val; }
|
|
280
|
+
|
|
281
|
+
static const cpp_dec_float& long_double_min()
|
|
282
|
+
{
|
|
283
|
+
#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
|
284
|
+
static const cpp_dec_float val(static_cast<long double>((std::numeric_limits<double>::min)()));
|
|
285
|
+
#else
|
|
286
|
+
static const cpp_dec_float val((std::numeric_limits<long double>::min)());
|
|
287
|
+
#endif
|
|
288
|
+
return val;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
static const cpp_dec_float& long_double_max()
|
|
292
|
+
{
|
|
293
|
+
#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
|
294
|
+
static const cpp_dec_float val(static_cast<long double>((std::numeric_limits<double>::max)()));
|
|
295
|
+
#else
|
|
296
|
+
static const cpp_dec_float val((std::numeric_limits<long double>::max)());
|
|
297
|
+
#endif
|
|
298
|
+
return val;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
static const cpp_dec_float& long_long_max () { static const cpp_dec_float val((std::numeric_limits<long long>::max)()); return val; }
|
|
302
|
+
static const cpp_dec_float& long_long_min () { static const cpp_dec_float val((std::numeric_limits<long long>::min)()); return val; }
|
|
303
|
+
static const cpp_dec_float& ulong_long_max() { static const cpp_dec_float val((std::numeric_limits<unsigned long long>::max)()); return val; }
|
|
304
|
+
|
|
305
|
+
static const cpp_dec_float& eps()
|
|
306
|
+
{
|
|
307
|
+
static const cpp_dec_float val
|
|
308
|
+
(
|
|
309
|
+
from_lst
|
|
310
|
+
(
|
|
311
|
+
{
|
|
312
|
+
(std::uint32_t) detail::pow10_maker((std::uint32_t) ((std::int32_t) (INT32_C(1) + (std::int32_t) (((cpp_dec_float_digits10 / cpp_dec_float_elem_digits10) + ((cpp_dec_float_digits10 % cpp_dec_float_elem_digits10) != 0 ? 1 : 0)) * cpp_dec_float_elem_digits10)) - cpp_dec_float_digits10))
|
|
313
|
+
},
|
|
314
|
+
-(exponent_type) (((cpp_dec_float_digits10 / cpp_dec_float_elem_digits10) + ((cpp_dec_float_digits10 % cpp_dec_float_elem_digits10) != 0 ? 1 : 0)) * cpp_dec_float_elem_digits10)
|
|
315
|
+
)
|
|
316
|
+
);
|
|
317
|
+
|
|
318
|
+
return val;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Basic operations.
|
|
322
|
+
cpp_dec_float& operator=(const cpp_dec_float& v) noexcept(noexcept(std::declval<array_type&>() = std::declval<const array_type&>()))
|
|
323
|
+
{
|
|
324
|
+
data = v.data;
|
|
325
|
+
exp = v.exp;
|
|
326
|
+
neg = v.neg;
|
|
327
|
+
fpclass = v.fpclass;
|
|
328
|
+
prec_elem = v.prec_elem;
|
|
329
|
+
return *this;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
template <unsigned D>
|
|
333
|
+
cpp_dec_float& operator=(const cpp_dec_float<D>& f)
|
|
334
|
+
{
|
|
335
|
+
exp = f.exp;
|
|
336
|
+
neg = f.neg;
|
|
337
|
+
fpclass = static_cast<enum_fpclass_type>(static_cast<int>(f.fpclass));
|
|
338
|
+
unsigned elems = (std::min)(f.prec_elem, cpp_dec_float_elem_number);
|
|
339
|
+
std::copy(f.data.begin(), f.data.begin() + elems, data.begin());
|
|
340
|
+
std::fill(data.begin() + elems, data.end(), 0);
|
|
341
|
+
prec_elem = cpp_dec_float_elem_number;
|
|
342
|
+
return *this;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
cpp_dec_float& operator=(long long v)
|
|
346
|
+
{
|
|
347
|
+
if (v < 0)
|
|
348
|
+
{
|
|
349
|
+
from_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(v));
|
|
350
|
+
negate();
|
|
351
|
+
}
|
|
352
|
+
else
|
|
353
|
+
{
|
|
354
|
+
using local_ulonglong_type = typename boost::multiprecision::detail::make_unsigned<long long>::type;
|
|
355
|
+
|
|
356
|
+
from_unsigned_long_long(static_cast<local_ulonglong_type>(v));
|
|
357
|
+
}
|
|
358
|
+
return *this;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
cpp_dec_float& operator=(unsigned long long v)
|
|
362
|
+
{
|
|
363
|
+
from_unsigned_long_long(v);
|
|
364
|
+
return *this;
|
|
365
|
+
}
|
|
366
|
+
#ifdef BOOST_HAS_INT128
|
|
367
|
+
cpp_dec_float& operator=(int128_type v)
|
|
368
|
+
{
|
|
369
|
+
*this = boost::multiprecision::detail::unsigned_abs(v);
|
|
370
|
+
if (v < 0)
|
|
371
|
+
negate();
|
|
372
|
+
return *this;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
cpp_dec_float& operator=(uint128_type v)
|
|
376
|
+
{
|
|
377
|
+
using default_ops::eval_add;
|
|
378
|
+
using default_ops::eval_multiply;
|
|
379
|
+
|
|
380
|
+
constexpr unsigned bit_shift = sizeof(unsigned long long) * CHAR_BIT;
|
|
381
|
+
constexpr uint128_type mask = (static_cast<uint128_type>(1u) << bit_shift) - 1;
|
|
382
|
+
|
|
383
|
+
*this = static_cast<unsigned long long>(v & mask);
|
|
384
|
+
|
|
385
|
+
v >>= bit_shift;
|
|
386
|
+
|
|
387
|
+
while (v)
|
|
388
|
+
{
|
|
389
|
+
cpp_dec_float t(static_cast<unsigned long long>(v & mask));
|
|
390
|
+
eval_multiply(t, cpp_dec_float::pow2(bit_shift));
|
|
391
|
+
eval_add(*this, t);
|
|
392
|
+
v >>= bit_shift;
|
|
393
|
+
}
|
|
394
|
+
return *this;
|
|
395
|
+
}
|
|
396
|
+
#endif
|
|
397
|
+
|
|
398
|
+
template <class Float>
|
|
399
|
+
typename std::enable_if<std::is_floating_point<Float>::value, cpp_dec_float&>::type operator=(Float v);
|
|
400
|
+
|
|
401
|
+
cpp_dec_float& operator=(const char* v)
|
|
402
|
+
{
|
|
403
|
+
rd_string(v);
|
|
404
|
+
return *this;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
cpp_dec_float& operator+=(const cpp_dec_float& v);
|
|
408
|
+
cpp_dec_float& operator-=(const cpp_dec_float& v);
|
|
409
|
+
cpp_dec_float& operator*=(const cpp_dec_float& v);
|
|
410
|
+
cpp_dec_float& operator/=(const cpp_dec_float& v);
|
|
411
|
+
|
|
412
|
+
cpp_dec_float& add_unsigned_long_long(const unsigned long long n)
|
|
413
|
+
{
|
|
414
|
+
cpp_dec_float t;
|
|
415
|
+
t.from_unsigned_long_long(n);
|
|
416
|
+
return *this += t;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
cpp_dec_float& sub_unsigned_long_long(const unsigned long long n)
|
|
420
|
+
{
|
|
421
|
+
cpp_dec_float t;
|
|
422
|
+
t.from_unsigned_long_long(n);
|
|
423
|
+
return *this -= t;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
cpp_dec_float& mul_unsigned_long_long(const unsigned long long n);
|
|
427
|
+
cpp_dec_float& div_unsigned_long_long(const unsigned long long n);
|
|
428
|
+
|
|
429
|
+
// Elementary primitives.
|
|
430
|
+
cpp_dec_float& calculate_inv();
|
|
431
|
+
cpp_dec_float& calculate_sqrt();
|
|
432
|
+
|
|
433
|
+
void negate()
|
|
434
|
+
{
|
|
435
|
+
if (!iszero())
|
|
436
|
+
neg = !neg;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Comparison functions
|
|
440
|
+
bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION() const { return (fpclass == cpp_dec_float_NaN); }
|
|
441
|
+
bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION() const { return (fpclass == cpp_dec_float_inf); }
|
|
442
|
+
bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION() const { return (fpclass == cpp_dec_float_finite); }
|
|
443
|
+
|
|
444
|
+
bool iszero() const
|
|
445
|
+
{
|
|
446
|
+
return ((fpclass == cpp_dec_float_finite) && (data[0u] == 0u));
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
bool isone() const;
|
|
450
|
+
bool isint() const;
|
|
451
|
+
bool isneg() const { return neg; }
|
|
452
|
+
|
|
453
|
+
// Operators pre-increment and pre-decrement
|
|
454
|
+
cpp_dec_float& operator++()
|
|
455
|
+
{
|
|
456
|
+
return *this += one();
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
cpp_dec_float& operator--()
|
|
460
|
+
{
|
|
461
|
+
return *this -= one();
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
std::string str(std::intmax_t digits, std::ios_base::fmtflags f) const;
|
|
465
|
+
|
|
466
|
+
int compare(const cpp_dec_float& v) const;
|
|
467
|
+
|
|
468
|
+
template <class V>
|
|
469
|
+
int compare(const V& v) const
|
|
470
|
+
{
|
|
471
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> t;
|
|
472
|
+
t = v;
|
|
473
|
+
return compare(t);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
void swap(cpp_dec_float& v)
|
|
477
|
+
{
|
|
478
|
+
data.swap(v.data);
|
|
479
|
+
std::swap(exp, v.exp);
|
|
480
|
+
std::swap(neg, v.neg);
|
|
481
|
+
std::swap(fpclass, v.fpclass);
|
|
482
|
+
std::swap(prec_elem, v.prec_elem);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
double extract_double() const;
|
|
486
|
+
long double extract_long_double() const;
|
|
487
|
+
long long extract_signed_long_long() const;
|
|
488
|
+
unsigned long long extract_unsigned_long_long() const;
|
|
489
|
+
#ifdef BOOST_HAS_INT128
|
|
490
|
+
int128_type extract_signed_int128() const;
|
|
491
|
+
uint128_type extract_unsigned_int128() const;
|
|
492
|
+
#endif
|
|
493
|
+
void extract_parts(double& mantissa, exponent_type& exponent) const;
|
|
494
|
+
cpp_dec_float extract_integer_part() const;
|
|
495
|
+
|
|
496
|
+
void precision(const std::int32_t prec_digits)
|
|
497
|
+
{
|
|
498
|
+
const std::int32_t elems =
|
|
499
|
+
static_cast<std::int32_t>( static_cast<std::int32_t>(prec_digits / cpp_dec_float_elem_digits10)
|
|
500
|
+
+ (((prec_digits % cpp_dec_float_elem_digits10) != 0) ? 1 : 0));
|
|
501
|
+
|
|
502
|
+
prec_elem = (std::min)(cpp_dec_float_elem_number, (std::max)(elems, static_cast<std::int32_t>(2)));
|
|
503
|
+
}
|
|
504
|
+
static cpp_dec_float pow2(long long i);
|
|
505
|
+
exponent_type order() const
|
|
506
|
+
{
|
|
507
|
+
const bool bo_order_is_zero = ((!(isfinite)()) || (data[0] == static_cast<std::uint32_t>(0u)));
|
|
508
|
+
//
|
|
509
|
+
// Binary search to find the order of the leading term:
|
|
510
|
+
//
|
|
511
|
+
exponent_type prefix = 0;
|
|
512
|
+
|
|
513
|
+
if (data[0] >= 100000UL)
|
|
514
|
+
{
|
|
515
|
+
if (data[0] >= 10000000UL)
|
|
516
|
+
{
|
|
517
|
+
if (data[0] >= 100000000UL)
|
|
518
|
+
{
|
|
519
|
+
if (data[0] >= 1000000000UL)
|
|
520
|
+
prefix = 9;
|
|
521
|
+
else
|
|
522
|
+
prefix = 8;
|
|
523
|
+
}
|
|
524
|
+
else
|
|
525
|
+
prefix = 7;
|
|
526
|
+
}
|
|
527
|
+
else
|
|
528
|
+
{
|
|
529
|
+
if (data[0] >= 1000000UL)
|
|
530
|
+
prefix = 6;
|
|
531
|
+
else
|
|
532
|
+
prefix = 5;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
else
|
|
536
|
+
{
|
|
537
|
+
if (data[0] >= 1000UL)
|
|
538
|
+
{
|
|
539
|
+
if (data[0] >= 10000UL)
|
|
540
|
+
prefix = 4;
|
|
541
|
+
else
|
|
542
|
+
prefix = 3;
|
|
543
|
+
}
|
|
544
|
+
else
|
|
545
|
+
{
|
|
546
|
+
if (data[0] >= 100)
|
|
547
|
+
prefix = 2;
|
|
548
|
+
else if (data[0] >= 10)
|
|
549
|
+
prefix = 1;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
return (bo_order_is_zero ? static_cast<exponent_type>(0) : static_cast<exponent_type>(exp + prefix));
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
#ifndef BOOST_MP_STANDALONE
|
|
557
|
+
template <class Archive>
|
|
558
|
+
void serialize(Archive& ar, const unsigned int /*version*/)
|
|
559
|
+
{
|
|
560
|
+
for (unsigned i = 0; i < data.size(); ++i)
|
|
561
|
+
ar& boost::make_nvp("digit", data[i]);
|
|
562
|
+
ar& boost::make_nvp("exponent", exp);
|
|
563
|
+
ar& boost::make_nvp("sign", neg);
|
|
564
|
+
ar& boost::make_nvp("class-type", fpclass);
|
|
565
|
+
ar& boost::make_nvp("precision", prec_elem);
|
|
566
|
+
}
|
|
567
|
+
#endif
|
|
568
|
+
|
|
569
|
+
private:
|
|
570
|
+
static bool data_elem_is_non_zero_predicate(const std::uint32_t& d) { return (d != static_cast<std::uint32_t>(0u)); }
|
|
571
|
+
static bool data_elem_is_non_nine_predicate(const std::uint32_t& d) { return (d != static_cast<std::uint32_t>(cpp_dec_float::cpp_dec_float_elem_mask - 1)); }
|
|
572
|
+
static bool char_is_nonzero_predicate(const char& c) { return (c != static_cast<char>('0')); }
|
|
573
|
+
|
|
574
|
+
void from_unsigned_long_long(const unsigned long long u);
|
|
575
|
+
|
|
576
|
+
template <typename InputIteratorTypeLeft,
|
|
577
|
+
typename InputIteratorTypeRight>
|
|
578
|
+
static int compare_ranges(InputIteratorTypeLeft a,
|
|
579
|
+
InputIteratorTypeRight b,
|
|
580
|
+
const std::uint32_t count = cpp_dec_float_elem_number);
|
|
581
|
+
|
|
582
|
+
static std::uint32_t eval_add_n( std::uint32_t* r,
|
|
583
|
+
const std::uint32_t* u,
|
|
584
|
+
const std::uint32_t* v,
|
|
585
|
+
const std::int32_t count);
|
|
586
|
+
|
|
587
|
+
static std::uint32_t eval_subtract_n( std::uint32_t* r,
|
|
588
|
+
const std::uint32_t* u,
|
|
589
|
+
const std::uint32_t* v,
|
|
590
|
+
const std::int32_t count);
|
|
591
|
+
|
|
592
|
+
static void eval_multiply_n_by_n_to_2n( std::uint32_t* r,
|
|
593
|
+
const std::uint32_t* a,
|
|
594
|
+
const std::uint32_t* b,
|
|
595
|
+
const std::uint32_t count);
|
|
596
|
+
|
|
597
|
+
static std::uint32_t mul_loop_n(std::uint32_t* const u, std::uint32_t n, const std::int32_t p);
|
|
598
|
+
static std::uint32_t div_loop_n(std::uint32_t* const u, std::uint32_t n, const std::int32_t p);
|
|
599
|
+
|
|
600
|
+
static void eval_multiply_kara_propagate_carry (std::uint32_t* t, const std::uint32_t n, const std::uint32_t carry);
|
|
601
|
+
static void eval_multiply_kara_propagate_borrow(std::uint32_t* t, const std::uint32_t n, const bool has_borrow);
|
|
602
|
+
static void eval_multiply_kara_n_by_n_to_2n ( std::uint32_t* r,
|
|
603
|
+
const std::uint32_t* a,
|
|
604
|
+
const std::uint32_t* b,
|
|
605
|
+
const std::uint32_t n,
|
|
606
|
+
std::uint32_t* t);
|
|
607
|
+
|
|
608
|
+
template<unsigned D>
|
|
609
|
+
void eval_mul_dispatch_multiplication_method(
|
|
610
|
+
const cpp_dec_float<D, ExponentType, Allocator>& v,
|
|
611
|
+
const std::int32_t prec_elems_for_multiply,
|
|
612
|
+
const typename std::enable_if< (D == Digits10)
|
|
613
|
+
&& (cpp_dec_float<D, ExponentType, Allocator>::cpp_dec_float_elem_number < cpp_dec_float_elems_for_kara)>::type* = nullptr)
|
|
614
|
+
{
|
|
615
|
+
// Use school multiplication.
|
|
616
|
+
|
|
617
|
+
using array_for_mul_result_type =
|
|
618
|
+
typename std::conditional<std::is_void<Allocator>::value,
|
|
619
|
+
detail::static_array <std::uint32_t, std::uint32_t(cpp_dec_float_elem_number * 2)>,
|
|
620
|
+
detail::dynamic_array<std::uint32_t, std::uint32_t(cpp_dec_float_elem_number * 2), Allocator> >::type;
|
|
621
|
+
|
|
622
|
+
array_for_mul_result_type result;
|
|
623
|
+
|
|
624
|
+
eval_multiply_n_by_n_to_2n(result.data(), data.data(), v.data.data(), static_cast<std::uint32_t>(prec_elems_for_multiply));
|
|
625
|
+
|
|
626
|
+
// Handle a potential carry.
|
|
627
|
+
if(result[0U] != static_cast<std::uint32_t>(0U))
|
|
628
|
+
{
|
|
629
|
+
exp += static_cast<exponent_type>(cpp_dec_float_elem_digits10);
|
|
630
|
+
|
|
631
|
+
// Shift the result of the multiplication one element to the right.
|
|
632
|
+
std::copy(result.cbegin(),
|
|
633
|
+
result.cbegin() + static_cast<std::ptrdiff_t>(prec_elems_for_multiply),
|
|
634
|
+
data.begin());
|
|
635
|
+
}
|
|
636
|
+
else
|
|
637
|
+
{
|
|
638
|
+
std::copy(result.cbegin() + static_cast<std::ptrdiff_t>(1),
|
|
639
|
+
result.cbegin() + static_cast<std::ptrdiff_t>(1 + (std::min)(prec_elems_for_multiply, cpp_dec_float_elem_number)),
|
|
640
|
+
data.begin());
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
template<unsigned D>
|
|
645
|
+
void eval_mul_dispatch_multiplication_method(
|
|
646
|
+
const cpp_dec_float<D, ExponentType, Allocator>& v,
|
|
647
|
+
const std::int32_t prec_elems_for_multiply,
|
|
648
|
+
const typename std::enable_if< (D == Digits10)
|
|
649
|
+
&& !(cpp_dec_float<D, ExponentType, Allocator>::cpp_dec_float_elem_number < cpp_dec_float_elems_for_kara)>::type* = nullptr)
|
|
650
|
+
{
|
|
651
|
+
if(prec_elems_for_multiply < cpp_dec_float_elems_for_kara)
|
|
652
|
+
{
|
|
653
|
+
// Use school multiplication.
|
|
654
|
+
|
|
655
|
+
using array_for_mul_result_type =
|
|
656
|
+
typename std::conditional<std::is_void<Allocator>::value,
|
|
657
|
+
detail::static_array <std::uint32_t, std::uint32_t(cpp_dec_float_elem_number * 2)>,
|
|
658
|
+
detail::dynamic_array<std::uint32_t, std::uint32_t(cpp_dec_float_elem_number * 2), Allocator> >::type;
|
|
659
|
+
|
|
660
|
+
array_for_mul_result_type result;
|
|
661
|
+
|
|
662
|
+
eval_multiply_n_by_n_to_2n(result.data(), data.data(), v.data.data(), static_cast<std::uint32_t>(prec_elems_for_multiply));
|
|
663
|
+
|
|
664
|
+
// Handle a potential carry.
|
|
665
|
+
if(result[0U] != static_cast<std::uint32_t>(0U))
|
|
666
|
+
{
|
|
667
|
+
exp += static_cast<exponent_type>(cpp_dec_float_elem_digits10);
|
|
668
|
+
|
|
669
|
+
// Shift the result of the multiplication one element to the right.
|
|
670
|
+
std::copy(result.cbegin(),
|
|
671
|
+
result.cbegin() + static_cast<std::ptrdiff_t>(prec_elems_for_multiply),
|
|
672
|
+
data.begin());
|
|
673
|
+
}
|
|
674
|
+
else
|
|
675
|
+
{
|
|
676
|
+
std::copy(result.cbegin() + static_cast<std::ptrdiff_t>(1),
|
|
677
|
+
result.cbegin() + static_cast<std::ptrdiff_t>(1 + (std::min)(prec_elems_for_multiply, cpp_dec_float_elem_number)),
|
|
678
|
+
data.begin());
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
else
|
|
682
|
+
{
|
|
683
|
+
// Use Karatsuba multiplication.
|
|
684
|
+
|
|
685
|
+
using array_for_kara_tmp_type =
|
|
686
|
+
typename std::conditional<std::is_void<Allocator>::value,
|
|
687
|
+
detail::static_array <std::uint32_t, detail::a029750::a029750_as_constexpr(static_cast<std::uint32_t>(cpp_dec_float_elem_number)) * 8U>,
|
|
688
|
+
detail::dynamic_array<std::uint32_t, detail::a029750::a029750_as_constexpr(static_cast<std::uint32_t>(cpp_dec_float_elem_number)) * 8U, Allocator> >::type;
|
|
689
|
+
|
|
690
|
+
// Sloanes's A029747: Numbers of the form 2^k times 1, 3 or 5.
|
|
691
|
+
const std::uint32_t kara_elems_for_multiply =
|
|
692
|
+
detail::a029750::a029750_as_runtime_value(static_cast<std::uint32_t>(prec_elems_for_multiply));
|
|
693
|
+
|
|
694
|
+
array_for_kara_tmp_type my_kara_mul_pool;
|
|
695
|
+
|
|
696
|
+
std::uint32_t* result = my_kara_mul_pool.data() + (kara_elems_for_multiply * 0U);
|
|
697
|
+
std::uint32_t* t = my_kara_mul_pool.data() + (kara_elems_for_multiply * 2U);
|
|
698
|
+
std::uint32_t* u_local = my_kara_mul_pool.data() + (kara_elems_for_multiply * 6U);
|
|
699
|
+
std::uint32_t* v_local = my_kara_mul_pool.data() + (kara_elems_for_multiply * 7U);
|
|
700
|
+
|
|
701
|
+
std::copy( data.cbegin(), data.cbegin() + prec_elems_for_multiply, u_local);
|
|
702
|
+
std::copy(v.data.cbegin(), v.data.cbegin() + prec_elems_for_multiply, v_local);
|
|
703
|
+
|
|
704
|
+
eval_multiply_kara_n_by_n_to_2n(result,
|
|
705
|
+
u_local,
|
|
706
|
+
v_local,
|
|
707
|
+
kara_elems_for_multiply,
|
|
708
|
+
t);
|
|
709
|
+
|
|
710
|
+
// Handle a potential carry.
|
|
711
|
+
if(result[0U] != static_cast<std::uint32_t>(0U))
|
|
712
|
+
{
|
|
713
|
+
exp += static_cast<exponent_type>(cpp_dec_float_elem_digits10);
|
|
714
|
+
|
|
715
|
+
// Shift the result of the multiplication one element to the right.
|
|
716
|
+
std::copy(result,
|
|
717
|
+
result + static_cast<std::ptrdiff_t>(prec_elems_for_multiply),
|
|
718
|
+
data.begin());
|
|
719
|
+
}
|
|
720
|
+
else
|
|
721
|
+
{
|
|
722
|
+
std::copy(result + static_cast<std::ptrdiff_t>(1),
|
|
723
|
+
result + static_cast<std::ptrdiff_t>(1 + (std::min)(prec_elems_for_multiply, cpp_dec_float_elem_number)),
|
|
724
|
+
data.begin());
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
bool rd_string(const char* const s);
|
|
730
|
+
|
|
731
|
+
template <unsigned D, class ET, class A>
|
|
732
|
+
friend class cpp_dec_float;
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
736
|
+
constexpr std::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_radix;
|
|
737
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
738
|
+
constexpr std::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10_limit_lo;
|
|
739
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
740
|
+
constexpr std::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10_limit_hi;
|
|
741
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
742
|
+
constexpr std::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10;
|
|
743
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
744
|
+
constexpr ExponentType cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_exp;
|
|
745
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
746
|
+
constexpr ExponentType cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp;
|
|
747
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
748
|
+
constexpr ExponentType cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_exp10;
|
|
749
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
750
|
+
constexpr ExponentType cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp10;
|
|
751
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
752
|
+
constexpr std::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_elem_digits10;
|
|
753
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
754
|
+
constexpr std::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_elem_number;
|
|
755
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
756
|
+
constexpr std::int32_t cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_elem_mask;
|
|
757
|
+
|
|
758
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
759
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator+=(const cpp_dec_float<Digits10, ExponentType, Allocator>& v)
|
|
760
|
+
{
|
|
761
|
+
if ((isnan)())
|
|
762
|
+
{
|
|
763
|
+
return *this;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
if ((isinf)())
|
|
767
|
+
{
|
|
768
|
+
if ((v.isinf)() && (isneg() != v.isneg()))
|
|
769
|
+
{
|
|
770
|
+
*this = nan();
|
|
771
|
+
}
|
|
772
|
+
return *this;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
if (iszero())
|
|
776
|
+
{
|
|
777
|
+
return operator=(v);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
if ((v.isnan)() || (v.isinf)())
|
|
781
|
+
{
|
|
782
|
+
*this = v;
|
|
783
|
+
return *this;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// Get the offset for the add/sub operation.
|
|
787
|
+
constexpr exponent_type max_delta_exp =
|
|
788
|
+
static_cast<exponent_type>((cpp_dec_float_elem_number - 1) * cpp_dec_float_elem_digits10);
|
|
789
|
+
|
|
790
|
+
const exponent_type ofs_exp = static_cast<exponent_type>(exp - v.exp);
|
|
791
|
+
|
|
792
|
+
// Check if the operation is out of range, requiring special handling.
|
|
793
|
+
if (v.iszero() || (ofs_exp > max_delta_exp))
|
|
794
|
+
{
|
|
795
|
+
// Result is *this unchanged since v is negligible compared to *this.
|
|
796
|
+
return *this;
|
|
797
|
+
}
|
|
798
|
+
else if (ofs_exp < -max_delta_exp)
|
|
799
|
+
{
|
|
800
|
+
// Result is *this = v since *this is negligible compared to v.
|
|
801
|
+
return operator=(v);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
// Do the add/sub operation.
|
|
805
|
+
|
|
806
|
+
typename array_type::pointer p_u = data.data();
|
|
807
|
+
typename array_type::const_pointer p_v = v.data.data();
|
|
808
|
+
bool b_copy = false;
|
|
809
|
+
const std::int32_t ofs = static_cast<std::int32_t>(static_cast<std::int32_t>(ofs_exp) / cpp_dec_float_elem_digits10);
|
|
810
|
+
array_type n_data;
|
|
811
|
+
|
|
812
|
+
if (neg == v.neg)
|
|
813
|
+
{
|
|
814
|
+
// Add v to *this, where the data array of either *this or v
|
|
815
|
+
// might have to be treated with a positive, negative or zero offset.
|
|
816
|
+
// The result is stored in *this. The data are added one element
|
|
817
|
+
// at a time, each element with carry.
|
|
818
|
+
if (ofs >= static_cast<std::int32_t>(0))
|
|
819
|
+
{
|
|
820
|
+
std::copy(v.data.cbegin(), v.data.cend() - static_cast<std::ptrdiff_t>(ofs), n_data.begin() + static_cast<std::ptrdiff_t>(ofs));
|
|
821
|
+
std::fill(n_data.begin(), n_data.begin() + static_cast<std::ptrdiff_t>(ofs), static_cast<std::uint32_t>(0u));
|
|
822
|
+
p_v = n_data.data();
|
|
823
|
+
}
|
|
824
|
+
else
|
|
825
|
+
{
|
|
826
|
+
std::copy(data.cbegin(), data.cend() - static_cast<std::ptrdiff_t>(-ofs), n_data.begin() + static_cast<std::ptrdiff_t>(-ofs));
|
|
827
|
+
std::fill(n_data.begin(), n_data.begin() + static_cast<std::ptrdiff_t>(-ofs), static_cast<std::uint32_t>(0u));
|
|
828
|
+
p_u = n_data.data();
|
|
829
|
+
b_copy = true;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
// Addition algorithm
|
|
833
|
+
const std::uint32_t carry = eval_add_n(p_u, p_u, p_v, cpp_dec_float_elem_number);
|
|
834
|
+
|
|
835
|
+
if (b_copy)
|
|
836
|
+
{
|
|
837
|
+
data = n_data;
|
|
838
|
+
exp = v.exp;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// There needs to be a carry into the element -1 of the array data
|
|
842
|
+
if (carry != static_cast<std::uint32_t>(0u))
|
|
843
|
+
{
|
|
844
|
+
std::copy_backward(data.cbegin(), data.cend() - static_cast<std::size_t>(1u), data.end());
|
|
845
|
+
data[0] = carry;
|
|
846
|
+
exp += static_cast<exponent_type>(cpp_dec_float_elem_digits10);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
else
|
|
850
|
+
{
|
|
851
|
+
// Subtract v from *this, where the data array of either *this or v
|
|
852
|
+
// might have to be treated with a positive, negative or zero offset.
|
|
853
|
+
if ((ofs > static_cast<std::int32_t>(0)) || ((ofs == static_cast<std::int32_t>(0)) && (compare_ranges(data.cbegin(), v.data.cbegin()) > static_cast<std::int32_t>(0))))
|
|
854
|
+
{
|
|
855
|
+
// In this case, |u| > |v| and ofs is positive.
|
|
856
|
+
// Copy the data of v, shifted down to a lower value
|
|
857
|
+
// into the data array m_n. Set the operand pointer p_v
|
|
858
|
+
// to point to the copied, shifted data m_n.
|
|
859
|
+
std::copy(v.data.cbegin(), v.data.cend() - static_cast<std::ptrdiff_t>(ofs), n_data.begin() + static_cast<std::ptrdiff_t>(ofs));
|
|
860
|
+
std::fill(n_data.begin(), n_data.begin() + static_cast<std::ptrdiff_t>(ofs), static_cast<std::uint32_t>(0u));
|
|
861
|
+
p_v = n_data.data();
|
|
862
|
+
}
|
|
863
|
+
else
|
|
864
|
+
{
|
|
865
|
+
if (ofs != static_cast<std::int32_t>(0))
|
|
866
|
+
{
|
|
867
|
+
// In this case, |u| < |v| and ofs is negative.
|
|
868
|
+
// Shift the data of u down to a lower value.
|
|
869
|
+
std::copy_backward(data.cbegin(), data.cend() - static_cast<std::ptrdiff_t>(-ofs), data.end());
|
|
870
|
+
std::fill(data.begin(), data.begin() + static_cast<std::ptrdiff_t>(-ofs), static_cast<std::uint32_t>(0u));
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
// Copy the data of v into the data array n_data.
|
|
874
|
+
// Set the u-pointer p_u to point to m_n and the
|
|
875
|
+
// operand pointer p_v to point to the shifted
|
|
876
|
+
// data m_data.
|
|
877
|
+
n_data = v.data;
|
|
878
|
+
p_u = n_data.data();
|
|
879
|
+
p_v = data.data();
|
|
880
|
+
b_copy = true;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
// Subtraction algorithm
|
|
884
|
+
static_cast<void>(eval_subtract_n(p_u, p_u, p_v, cpp_dec_float_elem_number));
|
|
885
|
+
|
|
886
|
+
if (b_copy)
|
|
887
|
+
{
|
|
888
|
+
data = n_data;
|
|
889
|
+
exp = v.exp;
|
|
890
|
+
neg = v.neg;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
// Is it necessary to justify the data?
|
|
894
|
+
const typename array_type::const_iterator first_nonzero_elem = std::find_if(data.begin(), data.end(), data_elem_is_non_zero_predicate);
|
|
895
|
+
|
|
896
|
+
if (first_nonzero_elem != data.begin())
|
|
897
|
+
{
|
|
898
|
+
if (first_nonzero_elem == data.end())
|
|
899
|
+
{
|
|
900
|
+
// This result of the subtraction is exactly zero.
|
|
901
|
+
// Reset the sign and the exponent.
|
|
902
|
+
neg = false;
|
|
903
|
+
exp = static_cast<exponent_type>(0);
|
|
904
|
+
}
|
|
905
|
+
else
|
|
906
|
+
{
|
|
907
|
+
// Justify the data
|
|
908
|
+
const std::size_t sj = static_cast<std::size_t>(std::distance<typename array_type::const_iterator>(data.begin(), first_nonzero_elem));
|
|
909
|
+
|
|
910
|
+
std::copy(data.begin() + static_cast<std::ptrdiff_t>(sj), data.end(), data.begin());
|
|
911
|
+
std::fill(data.end() - static_cast<std::ptrdiff_t>(sj), data.end(), static_cast<std::uint32_t>(0u));
|
|
912
|
+
|
|
913
|
+
exp -= static_cast<exponent_type>(sj * static_cast<std::size_t>(cpp_dec_float_elem_digits10));
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
// Handle underflow.
|
|
919
|
+
if (iszero())
|
|
920
|
+
return (*this = zero());
|
|
921
|
+
|
|
922
|
+
// Check for potential overflow.
|
|
923
|
+
const bool b_result_might_overflow = (exp >= static_cast<exponent_type>(cpp_dec_float_max_exp10));
|
|
924
|
+
|
|
925
|
+
// Handle overflow.
|
|
926
|
+
if (b_result_might_overflow)
|
|
927
|
+
{
|
|
928
|
+
const bool b_result_is_neg = neg;
|
|
929
|
+
neg = false;
|
|
930
|
+
|
|
931
|
+
if (compare((cpp_dec_float::max)()) > 0)
|
|
932
|
+
*this = inf();
|
|
933
|
+
|
|
934
|
+
neg = b_result_is_neg;
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
return *this;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
941
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator-=(const cpp_dec_float<Digits10, ExponentType, Allocator>& v)
|
|
942
|
+
{
|
|
943
|
+
// Use *this - v = -(-*this + v).
|
|
944
|
+
negate();
|
|
945
|
+
*this += v;
|
|
946
|
+
negate();
|
|
947
|
+
return *this;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
951
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator*=(const cpp_dec_float<Digits10, ExponentType, Allocator>& v)
|
|
952
|
+
{
|
|
953
|
+
// Evaluate the sign of the result.
|
|
954
|
+
const bool b_result_is_neg = (neg != v.neg);
|
|
955
|
+
|
|
956
|
+
// Artificially set the sign of the result to be positive.
|
|
957
|
+
neg = false;
|
|
958
|
+
|
|
959
|
+
// Handle special cases like zero, inf and NaN.
|
|
960
|
+
const bool b_u_is_inf = (isinf)();
|
|
961
|
+
const bool b_v_is_inf = (v.isinf)();
|
|
962
|
+
const bool b_u_is_zero = iszero();
|
|
963
|
+
const bool b_v_is_zero = v.iszero();
|
|
964
|
+
|
|
965
|
+
if (((isnan)() || (v.isnan)()) || (b_u_is_inf && b_v_is_zero) || (b_v_is_inf && b_u_is_zero))
|
|
966
|
+
{
|
|
967
|
+
*this = nan();
|
|
968
|
+
return *this;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
if (b_u_is_inf || b_v_is_inf)
|
|
972
|
+
{
|
|
973
|
+
*this = inf();
|
|
974
|
+
if (b_result_is_neg)
|
|
975
|
+
negate();
|
|
976
|
+
return *this;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
if (b_u_is_zero || b_v_is_zero)
|
|
980
|
+
{
|
|
981
|
+
return *this = zero();
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
// Check for potential overflow or underflow.
|
|
985
|
+
const bool b_result_might_overflow = ((exp + v.exp) >= static_cast<exponent_type>(cpp_dec_float_max_exp10));
|
|
986
|
+
const bool b_result_might_underflow = ((exp + v.exp) <= static_cast<exponent_type>(cpp_dec_float_min_exp10));
|
|
987
|
+
|
|
988
|
+
// Set the exponent of the result.
|
|
989
|
+
exp += v.exp;
|
|
990
|
+
|
|
991
|
+
const std::int32_t prec_mul = (std::min)(prec_elem, v.prec_elem);
|
|
992
|
+
|
|
993
|
+
eval_mul_dispatch_multiplication_method(v, prec_mul);
|
|
994
|
+
|
|
995
|
+
// Handle overflow.
|
|
996
|
+
if (b_result_might_overflow && (compare((cpp_dec_float::max)()) > 0))
|
|
997
|
+
{
|
|
998
|
+
*this = inf();
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
// Handle underflow.
|
|
1002
|
+
if (b_result_might_underflow && (compare((cpp_dec_float::min)()) < 0))
|
|
1003
|
+
{
|
|
1004
|
+
*this = zero();
|
|
1005
|
+
|
|
1006
|
+
return *this;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
// Set the sign of the result.
|
|
1010
|
+
neg = b_result_is_neg;
|
|
1011
|
+
|
|
1012
|
+
return *this;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1016
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::operator/=(const cpp_dec_float<Digits10, ExponentType, Allocator>& v)
|
|
1017
|
+
{
|
|
1018
|
+
if (iszero())
|
|
1019
|
+
{
|
|
1020
|
+
if ((v.isnan)())
|
|
1021
|
+
{
|
|
1022
|
+
return *this = v;
|
|
1023
|
+
}
|
|
1024
|
+
else if (v.iszero())
|
|
1025
|
+
{
|
|
1026
|
+
return *this = nan();
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
const bool u_and_v_are_finite_and_identical = ((isfinite)() && (fpclass == v.fpclass) && (exp == v.exp) && (compare_ranges(data.cbegin(), v.data.cbegin()) == static_cast<std::int32_t>(0)));
|
|
1031
|
+
|
|
1032
|
+
if (u_and_v_are_finite_and_identical)
|
|
1033
|
+
{
|
|
1034
|
+
if (neg != v.neg)
|
|
1035
|
+
{
|
|
1036
|
+
*this = one();
|
|
1037
|
+
negate();
|
|
1038
|
+
}
|
|
1039
|
+
else
|
|
1040
|
+
*this = one();
|
|
1041
|
+
return *this;
|
|
1042
|
+
}
|
|
1043
|
+
else
|
|
1044
|
+
{
|
|
1045
|
+
cpp_dec_float t(v);
|
|
1046
|
+
t.calculate_inv();
|
|
1047
|
+
return operator*=(t);
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1052
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::mul_unsigned_long_long(const unsigned long long n)
|
|
1053
|
+
{
|
|
1054
|
+
// Multiply *this with a constant unsigned long long.
|
|
1055
|
+
|
|
1056
|
+
// Evaluate the sign of the result.
|
|
1057
|
+
const bool b_neg = neg;
|
|
1058
|
+
|
|
1059
|
+
// Artificially set the sign of the result to be positive.
|
|
1060
|
+
neg = false;
|
|
1061
|
+
|
|
1062
|
+
// Handle special cases like zero, inf and NaN.
|
|
1063
|
+
const bool b_u_is_inf = (isinf)();
|
|
1064
|
+
const bool b_n_is_zero = (n == static_cast<std::int32_t>(0));
|
|
1065
|
+
|
|
1066
|
+
if ((isnan)() || (b_u_is_inf && b_n_is_zero))
|
|
1067
|
+
{
|
|
1068
|
+
return (*this = nan());
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
if (b_u_is_inf)
|
|
1072
|
+
{
|
|
1073
|
+
*this = inf();
|
|
1074
|
+
if (b_neg)
|
|
1075
|
+
negate();
|
|
1076
|
+
return *this;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
if (iszero() || b_n_is_zero)
|
|
1080
|
+
{
|
|
1081
|
+
// Multiplication by zero.
|
|
1082
|
+
return *this = zero();
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
if (n >= static_cast<unsigned long long>(cpp_dec_float_elem_mask))
|
|
1086
|
+
{
|
|
1087
|
+
neg = b_neg;
|
|
1088
|
+
cpp_dec_float t;
|
|
1089
|
+
t = n;
|
|
1090
|
+
return operator*=(t);
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
if (n == static_cast<unsigned long long>(1u))
|
|
1094
|
+
{
|
|
1095
|
+
neg = b_neg;
|
|
1096
|
+
return *this;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
// Set up the multiplication loop.
|
|
1100
|
+
const std::uint32_t nn = static_cast<std::uint32_t>(n);
|
|
1101
|
+
const std::uint32_t carry = mul_loop_n(data.data(), nn, prec_elem);
|
|
1102
|
+
|
|
1103
|
+
// Handle the carry and adjust the exponent.
|
|
1104
|
+
if (carry != static_cast<std::uint32_t>(0u))
|
|
1105
|
+
{
|
|
1106
|
+
exp += static_cast<exponent_type>(cpp_dec_float_elem_digits10);
|
|
1107
|
+
|
|
1108
|
+
// Shift the result of the multiplication one element to the right.
|
|
1109
|
+
std::copy_backward(data.begin(),
|
|
1110
|
+
data.begin() + static_cast<std::ptrdiff_t>(prec_elem - static_cast<std::int32_t>(1)),
|
|
1111
|
+
data.begin() + static_cast<std::ptrdiff_t>(prec_elem));
|
|
1112
|
+
|
|
1113
|
+
data.front() = static_cast<std::uint32_t>(carry);
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
// Check for potential overflow.
|
|
1117
|
+
const bool b_result_might_overflow = (exp >= cpp_dec_float_max_exp10);
|
|
1118
|
+
|
|
1119
|
+
// Handle overflow.
|
|
1120
|
+
if (b_result_might_overflow && (compare((cpp_dec_float::max)()) > 0))
|
|
1121
|
+
{
|
|
1122
|
+
*this = inf();
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
// Set the sign.
|
|
1126
|
+
neg = b_neg;
|
|
1127
|
+
|
|
1128
|
+
return *this;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1132
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::div_unsigned_long_long(const unsigned long long n)
|
|
1133
|
+
{
|
|
1134
|
+
// Divide *this by a constant unsigned long long.
|
|
1135
|
+
|
|
1136
|
+
// Evaluate the sign of the result.
|
|
1137
|
+
const bool b_neg = neg;
|
|
1138
|
+
|
|
1139
|
+
// Artificially set the sign of the result to be positive.
|
|
1140
|
+
neg = false;
|
|
1141
|
+
|
|
1142
|
+
// Handle special cases like zero, inf and NaN.
|
|
1143
|
+
if ((isnan)())
|
|
1144
|
+
{
|
|
1145
|
+
return *this;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
if ((isinf)())
|
|
1149
|
+
{
|
|
1150
|
+
*this = inf();
|
|
1151
|
+
if (b_neg)
|
|
1152
|
+
negate();
|
|
1153
|
+
return *this;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
if (n == static_cast<unsigned long long>(0u))
|
|
1157
|
+
{
|
|
1158
|
+
// Divide by 0.
|
|
1159
|
+
if (iszero())
|
|
1160
|
+
{
|
|
1161
|
+
*this = nan();
|
|
1162
|
+
return *this;
|
|
1163
|
+
}
|
|
1164
|
+
else
|
|
1165
|
+
{
|
|
1166
|
+
*this = inf();
|
|
1167
|
+
if (isneg())
|
|
1168
|
+
negate();
|
|
1169
|
+
return *this;
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
if (iszero())
|
|
1174
|
+
{
|
|
1175
|
+
return *this;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
if (n >= static_cast<unsigned long long>(cpp_dec_float_elem_mask))
|
|
1179
|
+
{
|
|
1180
|
+
neg = b_neg;
|
|
1181
|
+
cpp_dec_float t;
|
|
1182
|
+
t = n;
|
|
1183
|
+
return operator/=(t);
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
const std::uint32_t nn = static_cast<std::uint32_t>(n);
|
|
1187
|
+
|
|
1188
|
+
if (nn > static_cast<std::uint32_t>(1u))
|
|
1189
|
+
{
|
|
1190
|
+
// Do the division loop.
|
|
1191
|
+
const std::uint32_t prev = div_loop_n(data.data(), nn, prec_elem);
|
|
1192
|
+
|
|
1193
|
+
// Determine if one leading zero is in the result data.
|
|
1194
|
+
if (data[0] == static_cast<std::uint32_t>(0u))
|
|
1195
|
+
{
|
|
1196
|
+
// Adjust the exponent
|
|
1197
|
+
exp -= static_cast<exponent_type>(cpp_dec_float_elem_digits10);
|
|
1198
|
+
|
|
1199
|
+
// Shift result of the division one element to the left.
|
|
1200
|
+
std::copy(data.begin() + static_cast<std::ptrdiff_t>(1),
|
|
1201
|
+
data.begin() + static_cast<std::ptrdiff_t>(prec_elem - static_cast<std::int32_t>(1)),
|
|
1202
|
+
data.begin());
|
|
1203
|
+
|
|
1204
|
+
data[static_cast<std::size_t>(prec_elem - static_cast<std::int32_t>(1))] = static_cast<std::uint32_t>(static_cast<std::uint64_t>(prev * static_cast<std::uint64_t>(cpp_dec_float_elem_mask)) / nn);
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
// Check for potential underflow.
|
|
1209
|
+
const bool b_result_might_underflow = (exp <= cpp_dec_float_min_exp10);
|
|
1210
|
+
|
|
1211
|
+
// Handle underflow.
|
|
1212
|
+
if (b_result_might_underflow && (compare((cpp_dec_float::min)()) < 0))
|
|
1213
|
+
return (*this = zero());
|
|
1214
|
+
|
|
1215
|
+
// Set the sign of the result.
|
|
1216
|
+
neg = b_neg;
|
|
1217
|
+
|
|
1218
|
+
return *this;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1222
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::calculate_inv()
|
|
1223
|
+
{
|
|
1224
|
+
// Compute the inverse of *this.
|
|
1225
|
+
const bool b_neg = neg;
|
|
1226
|
+
|
|
1227
|
+
neg = false;
|
|
1228
|
+
|
|
1229
|
+
// Handle special cases like zero, inf and NaN.
|
|
1230
|
+
if (iszero())
|
|
1231
|
+
{
|
|
1232
|
+
*this = inf();
|
|
1233
|
+
if (b_neg)
|
|
1234
|
+
negate();
|
|
1235
|
+
return *this;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
if ((isnan)())
|
|
1239
|
+
{
|
|
1240
|
+
return *this;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
if ((isinf)())
|
|
1244
|
+
{
|
|
1245
|
+
return *this = zero();
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
if (isone())
|
|
1249
|
+
{
|
|
1250
|
+
if (b_neg)
|
|
1251
|
+
negate();
|
|
1252
|
+
return *this;
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
// Save the original *this.
|
|
1256
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> x(*this);
|
|
1257
|
+
|
|
1258
|
+
// Generate the initial estimate using division.
|
|
1259
|
+
// Extract the mantissa and exponent for a "manual"
|
|
1260
|
+
// computation of the estimate.
|
|
1261
|
+
double dd;
|
|
1262
|
+
exponent_type ne;
|
|
1263
|
+
x.extract_parts(dd, ne);
|
|
1264
|
+
|
|
1265
|
+
// Do the inverse estimate using double precision estimates of mantissa and exponent.
|
|
1266
|
+
operator=(cpp_dec_float<Digits10, ExponentType, Allocator>(1.0 / dd, -ne));
|
|
1267
|
+
|
|
1268
|
+
// Compute the inverse of *this. Quadratically convergent Newton-Raphson iteration
|
|
1269
|
+
// is used. During the iterative steps, the precision of the calculation is limited
|
|
1270
|
+
// to the minimum required in order to minimize the run-time.
|
|
1271
|
+
|
|
1272
|
+
constexpr std::int32_t double_digits10_minus_a_few = std::numeric_limits<double>::digits10 - 3;
|
|
1273
|
+
|
|
1274
|
+
for (std::int32_t digits = double_digits10_minus_a_few; digits <= cpp_dec_float_max_digits10; digits *= static_cast<std::int32_t>(2))
|
|
1275
|
+
{
|
|
1276
|
+
// Adjust precision of the terms.
|
|
1277
|
+
precision(static_cast<std::int32_t>((digits + 10) * static_cast<std::int32_t>(2)));
|
|
1278
|
+
x.precision(static_cast<std::int32_t>((digits + 10) * static_cast<std::int32_t>(2)));
|
|
1279
|
+
|
|
1280
|
+
// Next iteration.
|
|
1281
|
+
cpp_dec_float t(*this);
|
|
1282
|
+
t *= x;
|
|
1283
|
+
t -= two();
|
|
1284
|
+
t.negate();
|
|
1285
|
+
*this *= t;
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
neg = b_neg;
|
|
1289
|
+
|
|
1290
|
+
prec_elem = cpp_dec_float_elem_number;
|
|
1291
|
+
|
|
1292
|
+
return *this;
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1296
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, ExponentType, Allocator>::calculate_sqrt()
|
|
1297
|
+
{
|
|
1298
|
+
// Compute the square root of *this.
|
|
1299
|
+
|
|
1300
|
+
if ((isinf)() && !isneg())
|
|
1301
|
+
{
|
|
1302
|
+
return *this;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
if (isneg() || (!(isfinite)()))
|
|
1306
|
+
{
|
|
1307
|
+
*this = nan();
|
|
1308
|
+
errno = EDOM;
|
|
1309
|
+
return *this;
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
if (iszero() || isone())
|
|
1313
|
+
{
|
|
1314
|
+
return *this;
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
// Save the original *this.
|
|
1318
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> x(*this);
|
|
1319
|
+
|
|
1320
|
+
// Generate the initial estimate using division.
|
|
1321
|
+
// Extract the mantissa and exponent for a "manual"
|
|
1322
|
+
// computation of the estimate.
|
|
1323
|
+
double dd;
|
|
1324
|
+
exponent_type ne;
|
|
1325
|
+
extract_parts(dd, ne);
|
|
1326
|
+
|
|
1327
|
+
// Force the exponent to be an even multiple of two.
|
|
1328
|
+
if ((ne % static_cast<exponent_type>(2)) != static_cast<exponent_type>(0))
|
|
1329
|
+
{
|
|
1330
|
+
++ne;
|
|
1331
|
+
dd /= 10.0;
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
// Setup the iteration.
|
|
1335
|
+
// Estimate the square root using simple manipulations.
|
|
1336
|
+
const double sqd = std::sqrt(dd);
|
|
1337
|
+
|
|
1338
|
+
*this = cpp_dec_float<Digits10, ExponentType, Allocator>(sqd, static_cast<ExponentType>(ne / static_cast<ExponentType>(2)));
|
|
1339
|
+
|
|
1340
|
+
// Estimate 1.0 / (2.0 * x0) using simple manipulations.
|
|
1341
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> vi(0.5 / sqd, static_cast<ExponentType>(-ne / static_cast<ExponentType>(2)));
|
|
1342
|
+
|
|
1343
|
+
// Compute the square root of x. Coupled Newton iteration
|
|
1344
|
+
// as described in "Pi Unleashed" is used. During the
|
|
1345
|
+
// iterative steps, the precision of the calculation is
|
|
1346
|
+
// limited to the minimum required in order to minimize
|
|
1347
|
+
// the run-time.
|
|
1348
|
+
//
|
|
1349
|
+
// Book reference to "Pi Unleashed:
|
|
1350
|
+
// https://www.springer.com/gp/book/9783642567353
|
|
1351
|
+
|
|
1352
|
+
constexpr std::uint32_t double_digits10_minus_a_few = std::numeric_limits<double>::digits10 - 3;
|
|
1353
|
+
|
|
1354
|
+
for (std::int32_t digits = double_digits10_minus_a_few; digits <= cpp_dec_float_max_digits10; digits *= 2)
|
|
1355
|
+
{
|
|
1356
|
+
// Adjust precision of the terms.
|
|
1357
|
+
precision((digits + 10) * 2);
|
|
1358
|
+
vi.precision((digits + 10) * 2);
|
|
1359
|
+
|
|
1360
|
+
// Next iteration of vi
|
|
1361
|
+
cpp_dec_float t(*this);
|
|
1362
|
+
t *= vi;
|
|
1363
|
+
t.negate();
|
|
1364
|
+
t.mul_unsigned_long_long(2u);
|
|
1365
|
+
t += one();
|
|
1366
|
+
t *= vi;
|
|
1367
|
+
vi += t;
|
|
1368
|
+
|
|
1369
|
+
// Next iteration of *this
|
|
1370
|
+
t = *this;
|
|
1371
|
+
t *= *this;
|
|
1372
|
+
t.negate();
|
|
1373
|
+
t += x;
|
|
1374
|
+
t *= vi;
|
|
1375
|
+
*this += t;
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
prec_elem = cpp_dec_float_elem_number;
|
|
1379
|
+
|
|
1380
|
+
return *this;
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1384
|
+
int cpp_dec_float<Digits10, ExponentType, Allocator>::compare(const cpp_dec_float& v) const
|
|
1385
|
+
{
|
|
1386
|
+
// Compare v with *this.
|
|
1387
|
+
// Return +1 for *this > v
|
|
1388
|
+
// 0 for *this = v
|
|
1389
|
+
// -1 for *this < v
|
|
1390
|
+
|
|
1391
|
+
// Handle all non-finite cases.
|
|
1392
|
+
if ((!(isfinite)()) || (!(v.isfinite)()))
|
|
1393
|
+
{
|
|
1394
|
+
// NaN can never equal NaN. Return an implementation-dependent
|
|
1395
|
+
// signed result. Also note that comparison of NaN with NaN
|
|
1396
|
+
// using operators greater-than or less-than is undefined.
|
|
1397
|
+
if ((isnan)() || (v.isnan)())
|
|
1398
|
+
{
|
|
1399
|
+
return ((isnan)() ? 1 : -1);
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
if ((isinf)() && (v.isinf)())
|
|
1403
|
+
{
|
|
1404
|
+
// Both *this and v are infinite. They are equal if they have the same sign.
|
|
1405
|
+
// Otherwise, *this is less than v if and only if *this is negative.
|
|
1406
|
+
return ((neg == v.neg) ? 0 : (neg ? -1 : 1));
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
if ((isinf)())
|
|
1410
|
+
{
|
|
1411
|
+
// *this is infinite, but v is finite.
|
|
1412
|
+
// So negative infinite *this is less than any finite v.
|
|
1413
|
+
// Whereas positive infinite *this is greater than any finite v.
|
|
1414
|
+
return (isneg() ? -1 : 1);
|
|
1415
|
+
}
|
|
1416
|
+
else
|
|
1417
|
+
{
|
|
1418
|
+
// *this is finite, and v is infinite.
|
|
1419
|
+
// So any finite *this is greater than negative infinite v.
|
|
1420
|
+
// Whereas any finite *this is less than positive infinite v.
|
|
1421
|
+
return (v.neg ? 1 : -1);
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
// And now handle all *finite* cases.
|
|
1426
|
+
if (iszero())
|
|
1427
|
+
{
|
|
1428
|
+
// The value of *this is zero and v is either zero or non-zero.
|
|
1429
|
+
return (v.iszero() ? 0
|
|
1430
|
+
: (v.neg ? 1 : -1));
|
|
1431
|
+
}
|
|
1432
|
+
else if (v.iszero())
|
|
1433
|
+
{
|
|
1434
|
+
// The value of v is zero and *this is non-zero.
|
|
1435
|
+
return (neg ? -1 : 1);
|
|
1436
|
+
}
|
|
1437
|
+
else
|
|
1438
|
+
{
|
|
1439
|
+
// Both *this and v are non-zero.
|
|
1440
|
+
|
|
1441
|
+
if (neg != v.neg)
|
|
1442
|
+
{
|
|
1443
|
+
// The signs are different.
|
|
1444
|
+
return (neg ? -1 : 1);
|
|
1445
|
+
}
|
|
1446
|
+
else if (exp != v.exp)
|
|
1447
|
+
{
|
|
1448
|
+
// The signs are the same and the exponents are different.
|
|
1449
|
+
const int val_cexpression = ((exp < v.exp) ? 1 : -1);
|
|
1450
|
+
|
|
1451
|
+
return (neg ? val_cexpression : -val_cexpression);
|
|
1452
|
+
}
|
|
1453
|
+
else
|
|
1454
|
+
{
|
|
1455
|
+
// The signs are the same and the exponents are the same.
|
|
1456
|
+
// Compare the data.
|
|
1457
|
+
const int val_cmp_data = compare_ranges(data.cbegin(), v.data.cbegin());
|
|
1458
|
+
|
|
1459
|
+
return ((!neg) ? val_cmp_data : -val_cmp_data);
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1465
|
+
bool cpp_dec_float<Digits10, ExponentType, Allocator>::isone() const
|
|
1466
|
+
{
|
|
1467
|
+
// Check if the value of *this is identically 1 or very close to 1.
|
|
1468
|
+
|
|
1469
|
+
const bool not_negative_and_is_finite = ((!neg) && (isfinite)());
|
|
1470
|
+
|
|
1471
|
+
if (not_negative_and_is_finite)
|
|
1472
|
+
{
|
|
1473
|
+
if ((data[0u] == static_cast<std::uint32_t>(1u)) && (exp == static_cast<exponent_type>(0)))
|
|
1474
|
+
{
|
|
1475
|
+
const typename array_type::const_iterator it_non_zero = std::find_if(data.begin(), data.end(), data_elem_is_non_zero_predicate);
|
|
1476
|
+
return (it_non_zero == data.end());
|
|
1477
|
+
}
|
|
1478
|
+
else if ((data[0u] == static_cast<std::uint32_t>(cpp_dec_float_elem_mask - 1)) && (exp == static_cast<exponent_type>(-cpp_dec_float_elem_digits10)))
|
|
1479
|
+
{
|
|
1480
|
+
const typename array_type::const_iterator it_non_nine = std::find_if(data.begin(), data.end(), data_elem_is_non_nine_predicate);
|
|
1481
|
+
return (it_non_nine == data.end());
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
return false;
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1489
|
+
bool cpp_dec_float<Digits10, ExponentType, Allocator>::isint() const
|
|
1490
|
+
{
|
|
1491
|
+
if (fpclass != cpp_dec_float_finite)
|
|
1492
|
+
{
|
|
1493
|
+
return false;
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
if (iszero())
|
|
1497
|
+
{
|
|
1498
|
+
return true;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
if (exp < static_cast<exponent_type>(0))
|
|
1502
|
+
{
|
|
1503
|
+
return false;
|
|
1504
|
+
} // |*this| < 1.
|
|
1505
|
+
|
|
1506
|
+
const typename array_type::size_type offset_decimal_part = static_cast<typename array_type::size_type>(exp / cpp_dec_float_elem_digits10) + 1u;
|
|
1507
|
+
|
|
1508
|
+
if (offset_decimal_part >= static_cast<typename array_type::size_type>(cpp_dec_float_elem_number))
|
|
1509
|
+
{
|
|
1510
|
+
// The number is too large to resolve the integer part.
|
|
1511
|
+
// It considered to be a pure integer.
|
|
1512
|
+
return true;
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
typename array_type::const_iterator it_non_zero = std::find_if(data.begin() + static_cast<std::ptrdiff_t>(offset_decimal_part), data.end(), data_elem_is_non_zero_predicate);
|
|
1516
|
+
|
|
1517
|
+
return (it_non_zero == data.end());
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1521
|
+
void cpp_dec_float<Digits10, ExponentType, Allocator>::extract_parts(double& mantissa, ExponentType& exponent) const
|
|
1522
|
+
{
|
|
1523
|
+
// Extract the approximate parts mantissa and base-10 exponent from the input cpp_dec_float<Digits10, ExponentType, Allocator> value x.
|
|
1524
|
+
|
|
1525
|
+
// Extracts the mantissa and exponent.
|
|
1526
|
+
exponent = exp;
|
|
1527
|
+
|
|
1528
|
+
std::uint32_t p10 = static_cast<std::uint32_t>(1u);
|
|
1529
|
+
std::uint32_t test = data[0u];
|
|
1530
|
+
|
|
1531
|
+
for (;;)
|
|
1532
|
+
{
|
|
1533
|
+
test /= static_cast<std::uint32_t>(10u);
|
|
1534
|
+
|
|
1535
|
+
if (test == static_cast<std::uint32_t>(0u))
|
|
1536
|
+
{
|
|
1537
|
+
break;
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
p10 *= static_cast<std::uint32_t>(10u);
|
|
1541
|
+
++exponent;
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
// Establish the upper bound of limbs for extracting the double.
|
|
1545
|
+
const int max_elem_in_double_count = static_cast<int>(static_cast<std::int32_t>(std::numeric_limits<double>::digits10) / cpp_dec_float_elem_digits10) + (static_cast<int>(static_cast<std::int32_t>(std::numeric_limits<double>::digits10) % cpp_dec_float_elem_digits10) != 0 ? 1 : 0) + 1;
|
|
1546
|
+
|
|
1547
|
+
// And make sure this upper bound stays within bounds of the elems.
|
|
1548
|
+
const std::size_t max_elem_extract_count = static_cast<std::size_t>((std::min)(static_cast<std::int32_t>(max_elem_in_double_count), cpp_dec_float_elem_number));
|
|
1549
|
+
|
|
1550
|
+
// Extract into the mantissa the first limb, extracted as a double.
|
|
1551
|
+
mantissa = static_cast<double>(data[0]);
|
|
1552
|
+
double scale = 1.0;
|
|
1553
|
+
|
|
1554
|
+
// Extract the rest of the mantissa piecewise from the limbs.
|
|
1555
|
+
for (std::size_t i = 1u; i < max_elem_extract_count; i++)
|
|
1556
|
+
{
|
|
1557
|
+
scale /= static_cast<double>(cpp_dec_float_elem_mask);
|
|
1558
|
+
mantissa += (static_cast<double>(data[i]) * scale);
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
mantissa /= static_cast<double>(p10);
|
|
1562
|
+
|
|
1563
|
+
if (neg)
|
|
1564
|
+
{
|
|
1565
|
+
mantissa = -mantissa;
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1570
|
+
double cpp_dec_float<Digits10, ExponentType, Allocator>::extract_double() const
|
|
1571
|
+
{
|
|
1572
|
+
// Returns the double conversion of a cpp_dec_float<Digits10, ExponentType, Allocator>.
|
|
1573
|
+
|
|
1574
|
+
// Check for non-normal cpp_dec_float<Digits10, ExponentType, Allocator>.
|
|
1575
|
+
if (!(isfinite)())
|
|
1576
|
+
{
|
|
1577
|
+
if ((isnan)())
|
|
1578
|
+
{
|
|
1579
|
+
return std::numeric_limits<double>::quiet_NaN();
|
|
1580
|
+
}
|
|
1581
|
+
else
|
|
1582
|
+
{
|
|
1583
|
+
return ((!neg) ? std::numeric_limits<double>::infinity()
|
|
1584
|
+
: -std::numeric_limits<double>::infinity());
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> xx(*this);
|
|
1589
|
+
if (xx.isneg())
|
|
1590
|
+
xx.negate();
|
|
1591
|
+
|
|
1592
|
+
// Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> is zero.
|
|
1593
|
+
if (iszero() || (xx.compare(double_min()) < 0))
|
|
1594
|
+
{
|
|
1595
|
+
return 0.0;
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
// Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> exceeds the maximum of double.
|
|
1599
|
+
if (xx.compare(double_max()) > 0)
|
|
1600
|
+
{
|
|
1601
|
+
return ((!neg) ? std::numeric_limits<double>::infinity()
|
|
1602
|
+
: -std::numeric_limits<double>::infinity());
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1605
|
+
std::stringstream ss;
|
|
1606
|
+
ss.imbue(std::locale::classic());
|
|
1607
|
+
|
|
1608
|
+
ss << str(std::numeric_limits<double>::digits10 + (2 + 1), std::ios_base::scientific);
|
|
1609
|
+
|
|
1610
|
+
double d;
|
|
1611
|
+
ss >> d;
|
|
1612
|
+
|
|
1613
|
+
return d;
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1617
|
+
long double cpp_dec_float<Digits10, ExponentType, Allocator>::extract_long_double() const
|
|
1618
|
+
{
|
|
1619
|
+
// Returns the long double conversion of a cpp_dec_float<Digits10, ExponentType, Allocator>.
|
|
1620
|
+
|
|
1621
|
+
// Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> is subnormal.
|
|
1622
|
+
if (!(isfinite)())
|
|
1623
|
+
{
|
|
1624
|
+
if ((isnan)())
|
|
1625
|
+
{
|
|
1626
|
+
return std::numeric_limits<long double>::quiet_NaN();
|
|
1627
|
+
}
|
|
1628
|
+
else
|
|
1629
|
+
{
|
|
1630
|
+
return ((!neg) ? std::numeric_limits<long double>::infinity()
|
|
1631
|
+
: -std::numeric_limits<long double>::infinity());
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> xx(*this);
|
|
1636
|
+
if (xx.isneg())
|
|
1637
|
+
xx.negate();
|
|
1638
|
+
|
|
1639
|
+
// Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> is zero.
|
|
1640
|
+
if (iszero() || (xx.compare(long_double_min()) < 0))
|
|
1641
|
+
{
|
|
1642
|
+
return static_cast<long double>(0.0);
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
// Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> exceeds the maximum of double.
|
|
1646
|
+
if (xx.compare(long_double_max()) > 0)
|
|
1647
|
+
{
|
|
1648
|
+
return ((!neg) ? std::numeric_limits<long double>::infinity()
|
|
1649
|
+
: -std::numeric_limits<long double>::infinity());
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
std::stringstream ss;
|
|
1653
|
+
ss.imbue(std::locale::classic());
|
|
1654
|
+
|
|
1655
|
+
ss << str(std::numeric_limits<long double>::digits10 + (2 + 1), std::ios_base::scientific);
|
|
1656
|
+
|
|
1657
|
+
long double ld;
|
|
1658
|
+
ss >> ld;
|
|
1659
|
+
|
|
1660
|
+
return ld;
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1664
|
+
long long cpp_dec_float<Digits10, ExponentType, Allocator>::extract_signed_long_long() const
|
|
1665
|
+
{
|
|
1666
|
+
// Extracts a signed long long from *this.
|
|
1667
|
+
// If (x > maximum of long long) or (x < minimum of long long),
|
|
1668
|
+
// then the maximum or minimum of long long is returned accordingly.
|
|
1669
|
+
|
|
1670
|
+
if (exp < static_cast<exponent_type>(0))
|
|
1671
|
+
{
|
|
1672
|
+
return static_cast<long long>(0);
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
const bool b_neg = isneg();
|
|
1676
|
+
|
|
1677
|
+
unsigned long long val;
|
|
1678
|
+
|
|
1679
|
+
if ((!b_neg) && (compare(long_long_max()) > 0))
|
|
1680
|
+
{
|
|
1681
|
+
return (std::numeric_limits<long long>::max)();
|
|
1682
|
+
}
|
|
1683
|
+
else if (b_neg && (compare(long_long_min()) < 0))
|
|
1684
|
+
{
|
|
1685
|
+
return (std::numeric_limits<long long>::min)();
|
|
1686
|
+
}
|
|
1687
|
+
else
|
|
1688
|
+
{
|
|
1689
|
+
// Extract the data into an unsigned long long value.
|
|
1690
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> xn(extract_integer_part());
|
|
1691
|
+
if (xn.isneg())
|
|
1692
|
+
xn.negate();
|
|
1693
|
+
|
|
1694
|
+
val = static_cast<unsigned long long>(xn.data[0]);
|
|
1695
|
+
|
|
1696
|
+
const std::int32_t imax = (std::min)(static_cast<std::int32_t>(static_cast<std::int32_t>(xn.exp) / cpp_dec_float_elem_digits10), static_cast<std::int32_t>(cpp_dec_float_elem_number - static_cast<std::int32_t>(1)));
|
|
1697
|
+
|
|
1698
|
+
for (std::int32_t i = static_cast<std::int32_t>(1); i <= imax; i++)
|
|
1699
|
+
{
|
|
1700
|
+
val *= static_cast<unsigned long long>(cpp_dec_float_elem_mask);
|
|
1701
|
+
val += static_cast<unsigned long long>(xn.data[static_cast<std::size_t>(i)]);
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
if (!b_neg)
|
|
1706
|
+
{
|
|
1707
|
+
return static_cast<long long>(val);
|
|
1708
|
+
}
|
|
1709
|
+
else
|
|
1710
|
+
{
|
|
1711
|
+
// This strange expression avoids a hardware trap in the corner case
|
|
1712
|
+
// that val is the most negative value permitted in long long.
|
|
1713
|
+
// See https://svn.boost.org/trac/boost/ticket/9740.
|
|
1714
|
+
//
|
|
1715
|
+
long long sval = static_cast<long long>(val - 1);
|
|
1716
|
+
sval = -sval;
|
|
1717
|
+
--sval;
|
|
1718
|
+
return sval;
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1723
|
+
unsigned long long cpp_dec_float<Digits10, ExponentType, Allocator>::extract_unsigned_long_long() const
|
|
1724
|
+
{
|
|
1725
|
+
// Extracts an unsigned long long from *this.
|
|
1726
|
+
// If x exceeds the maximum of unsigned long long,
|
|
1727
|
+
// then the maximum of unsigned long long is returned.
|
|
1728
|
+
// If x is negative, then the unsigned long long cast of
|
|
1729
|
+
// the long long extracted value is returned.
|
|
1730
|
+
|
|
1731
|
+
if (isneg())
|
|
1732
|
+
{
|
|
1733
|
+
return static_cast<unsigned long long>(extract_signed_long_long());
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
if (exp < static_cast<exponent_type>(0))
|
|
1737
|
+
{
|
|
1738
|
+
return static_cast<unsigned long long>(0u);
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
const cpp_dec_float<Digits10, ExponentType, Allocator> xn(extract_integer_part());
|
|
1742
|
+
|
|
1743
|
+
unsigned long long val;
|
|
1744
|
+
|
|
1745
|
+
if (xn.compare(ulong_long_max()) > 0)
|
|
1746
|
+
{
|
|
1747
|
+
return (std::numeric_limits<unsigned long long>::max)();
|
|
1748
|
+
}
|
|
1749
|
+
else
|
|
1750
|
+
{
|
|
1751
|
+
// Extract the data into an unsigned long long value.
|
|
1752
|
+
val = static_cast<unsigned long long>(xn.data[0]);
|
|
1753
|
+
|
|
1754
|
+
const std::int32_t imax = (std::min)(static_cast<std::int32_t>(static_cast<std::int32_t>(xn.exp) / cpp_dec_float_elem_digits10), static_cast<std::int32_t>(cpp_dec_float_elem_number - static_cast<std::int32_t>(1)));
|
|
1755
|
+
|
|
1756
|
+
for (std::int32_t i = static_cast<std::int32_t>(1); i <= imax; i++)
|
|
1757
|
+
{
|
|
1758
|
+
val *= static_cast<unsigned long long>(cpp_dec_float_elem_mask);
|
|
1759
|
+
val += static_cast<unsigned long long>(xn.data[i]);
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
return val;
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
#ifdef BOOST_HAS_INT128
|
|
1767
|
+
|
|
1768
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1769
|
+
int128_type cpp_dec_float<Digits10, ExponentType, Allocator>::extract_signed_int128() const
|
|
1770
|
+
{
|
|
1771
|
+
// Extracts a signed __int128 from *this.
|
|
1772
|
+
// If (x > maximum of __int128) or (x < minimum of __int128),
|
|
1773
|
+
// then the maximum or minimum of long long is returned accordingly.
|
|
1774
|
+
|
|
1775
|
+
if (exp < static_cast<exponent_type>(0))
|
|
1776
|
+
{
|
|
1777
|
+
return static_cast<int128_type>(0);
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1780
|
+
const bool b_neg = isneg();
|
|
1781
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> i128max;
|
|
1782
|
+
i128max = ((~static_cast<uint128_type>(0)) >> 1);
|
|
1783
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> i128min;
|
|
1784
|
+
i128min = (-1 - static_cast<int128_type>((static_cast<uint128_type>(1) << 127) - 1));
|
|
1785
|
+
|
|
1786
|
+
uint128_type val;
|
|
1787
|
+
|
|
1788
|
+
if ((!b_neg) && (compare(i128max) > 0))
|
|
1789
|
+
{
|
|
1790
|
+
return ((~static_cast<uint128_type>(0)) >> 1);
|
|
1791
|
+
}
|
|
1792
|
+
else if (b_neg && (compare(i128min) < 0))
|
|
1793
|
+
{
|
|
1794
|
+
return (-1 - static_cast<int128_type>((static_cast<uint128_type>(1) << 127) - 1));
|
|
1795
|
+
}
|
|
1796
|
+
else
|
|
1797
|
+
{
|
|
1798
|
+
// Extract the data into an unsigned long long value.
|
|
1799
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> xn(extract_integer_part());
|
|
1800
|
+
if (xn.isneg())
|
|
1801
|
+
xn.negate();
|
|
1802
|
+
|
|
1803
|
+
val = static_cast<uint128_type>(xn.data[0]);
|
|
1804
|
+
|
|
1805
|
+
const std::int32_t imax = (std::min)(static_cast<std::int32_t>(static_cast<std::int32_t>(xn.exp) / cpp_dec_float_elem_digits10), static_cast<std::int32_t>(cpp_dec_float_elem_number - static_cast<std::int32_t>(1)));
|
|
1806
|
+
|
|
1807
|
+
for (std::int32_t i = static_cast<std::int32_t>(1); i <= imax; i++)
|
|
1808
|
+
{
|
|
1809
|
+
val *= static_cast<uint128_type>(cpp_dec_float_elem_mask);
|
|
1810
|
+
val += static_cast<uint128_type>(xn.data[static_cast<std::size_t>(i)]);
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
if (!b_neg)
|
|
1815
|
+
{
|
|
1816
|
+
return static_cast<int128_type>(val);
|
|
1817
|
+
}
|
|
1818
|
+
else
|
|
1819
|
+
{
|
|
1820
|
+
// This strange expression avoids a hardware trap in the corner case
|
|
1821
|
+
// that val is the most negative value permitted in long long.
|
|
1822
|
+
// See https://svn.boost.org/trac/boost/ticket/9740.
|
|
1823
|
+
//
|
|
1824
|
+
int128_type sval = static_cast<int128_type>(val - 1);
|
|
1825
|
+
sval = -sval;
|
|
1826
|
+
--sval;
|
|
1827
|
+
return sval;
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1832
|
+
uint128_type cpp_dec_float<Digits10, ExponentType, Allocator>::extract_unsigned_int128() const
|
|
1833
|
+
{
|
|
1834
|
+
// Extracts an unsigned __int128 from *this.
|
|
1835
|
+
// If x exceeds the maximum of unsigned __int128,
|
|
1836
|
+
// then the maximum of unsigned __int128 is returned.
|
|
1837
|
+
// If x is negative, then the unsigned __int128 cast of
|
|
1838
|
+
// the __int128 extracted value is returned.
|
|
1839
|
+
|
|
1840
|
+
if (isneg())
|
|
1841
|
+
{
|
|
1842
|
+
return static_cast<uint128_type>(extract_signed_int128());
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
if (exp < static_cast<exponent_type>(0))
|
|
1846
|
+
{
|
|
1847
|
+
return 0u;
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
const cpp_dec_float<Digits10, ExponentType, Allocator> xn(extract_integer_part());
|
|
1851
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> i128max;
|
|
1852
|
+
i128max = (~static_cast<uint128_type>(0));
|
|
1853
|
+
|
|
1854
|
+
uint128_type val;
|
|
1855
|
+
|
|
1856
|
+
if (xn.compare(i128max) > 0)
|
|
1857
|
+
{
|
|
1858
|
+
return (~static_cast<uint128_type>(0));
|
|
1859
|
+
}
|
|
1860
|
+
else
|
|
1861
|
+
{
|
|
1862
|
+
// Extract the data into an unsigned long long value.
|
|
1863
|
+
val = static_cast<uint128_type>(xn.data[0]);
|
|
1864
|
+
|
|
1865
|
+
const std::int32_t imax = (std::min)(static_cast<std::int32_t>(static_cast<std::int32_t>(xn.exp) / cpp_dec_float_elem_digits10), static_cast<std::int32_t>(cpp_dec_float_elem_number - static_cast<std::int32_t>(1)));
|
|
1866
|
+
|
|
1867
|
+
for (std::int32_t i = static_cast<std::int32_t>(1); i <= imax; i++)
|
|
1868
|
+
{
|
|
1869
|
+
val *= static_cast<uint128_type>(cpp_dec_float_elem_mask);
|
|
1870
|
+
val += static_cast<uint128_type>(xn.data[i]);
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
return val;
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
#endif
|
|
1878
|
+
|
|
1879
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1880
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> cpp_dec_float<Digits10, ExponentType, Allocator>::extract_integer_part() const
|
|
1881
|
+
{
|
|
1882
|
+
// Compute the signed integer part of x.
|
|
1883
|
+
|
|
1884
|
+
if (!(isfinite)())
|
|
1885
|
+
{
|
|
1886
|
+
return *this;
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
if (exp < static_cast<ExponentType>(0))
|
|
1890
|
+
{
|
|
1891
|
+
// The absolute value of the number is smaller than 1.
|
|
1892
|
+
// Thus the integer part is zero.
|
|
1893
|
+
return zero();
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
// Truncate the digits from the decimal part, including guard digits
|
|
1897
|
+
// that do not belong to the integer part.
|
|
1898
|
+
|
|
1899
|
+
// Make a local copy.
|
|
1900
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> x = *this;
|
|
1901
|
+
|
|
1902
|
+
// Clear out the decimal portion
|
|
1903
|
+
const std::size_t first_clear = (static_cast<std::size_t>(x.exp) / static_cast<std::size_t>(cpp_dec_float_elem_digits10)) + 1u;
|
|
1904
|
+
const std::size_t last_clear = static_cast<std::size_t>(cpp_dec_float_elem_number);
|
|
1905
|
+
|
|
1906
|
+
if (first_clear < last_clear)
|
|
1907
|
+
std::fill(x.data.begin() + static_cast<std::ptrdiff_t>(first_clear), x.data.begin() + static_cast<std::ptrdiff_t>(last_clear), static_cast<std::uint32_t>(0u));
|
|
1908
|
+
|
|
1909
|
+
return x;
|
|
1910
|
+
}
|
|
1911
|
+
|
|
1912
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
1913
|
+
std::string cpp_dec_float<Digits10, ExponentType, Allocator>::str(std::intmax_t number_of_digits, std::ios_base::fmtflags f) const
|
|
1914
|
+
{
|
|
1915
|
+
if ((this->isinf)())
|
|
1916
|
+
{
|
|
1917
|
+
if (this->isneg())
|
|
1918
|
+
return "-inf";
|
|
1919
|
+
else if (f & std::ios_base::showpos)
|
|
1920
|
+
return "+inf";
|
|
1921
|
+
else
|
|
1922
|
+
return "inf";
|
|
1923
|
+
}
|
|
1924
|
+
else if ((this->isnan)())
|
|
1925
|
+
{
|
|
1926
|
+
return "nan";
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1929
|
+
std::string str;
|
|
1930
|
+
std::intmax_t org_digits(number_of_digits);
|
|
1931
|
+
exponent_type my_exp = order();
|
|
1932
|
+
|
|
1933
|
+
if (!(f & std::ios_base::fixed) && (number_of_digits == 0))
|
|
1934
|
+
number_of_digits = cpp_dec_float_max_digits10;
|
|
1935
|
+
|
|
1936
|
+
if (f & std::ios_base::fixed)
|
|
1937
|
+
{
|
|
1938
|
+
number_of_digits += my_exp + 1;
|
|
1939
|
+
}
|
|
1940
|
+
else if (f & std::ios_base::scientific)
|
|
1941
|
+
++number_of_digits;
|
|
1942
|
+
// Determine the number of elements needed to provide the requested digits from cpp_dec_float<Digits10, ExponentType, Allocator>.
|
|
1943
|
+
const std::size_t number_of_elements = (std::min)(static_cast<std::size_t>(static_cast<std::size_t>(number_of_digits / static_cast<std::intmax_t>(cpp_dec_float_elem_digits10)) + 2u),
|
|
1944
|
+
static_cast<std::size_t>(cpp_dec_float_elem_number));
|
|
1945
|
+
|
|
1946
|
+
// Extract the remaining digits from cpp_dec_float<Digits10, ExponentType, Allocator> after the decimal point.
|
|
1947
|
+
std::stringstream ss;
|
|
1948
|
+
ss.imbue(std::locale::classic());
|
|
1949
|
+
ss << data[0];
|
|
1950
|
+
// Extract all of the digits from cpp_dec_float<Digits10, ExponentType, Allocator>, beginning with the first data element.
|
|
1951
|
+
for (std::size_t i = static_cast<std::size_t>(1u); i < number_of_elements; i++)
|
|
1952
|
+
{
|
|
1953
|
+
ss << std::setw(static_cast<std::streamsize>(cpp_dec_float_elem_digits10))
|
|
1954
|
+
<< std::setfill(static_cast<char>('0'))
|
|
1955
|
+
<< data[i];
|
|
1956
|
+
}
|
|
1957
|
+
str += ss.str();
|
|
1958
|
+
|
|
1959
|
+
bool have_leading_zeros = false;
|
|
1960
|
+
|
|
1961
|
+
if (number_of_digits == 0)
|
|
1962
|
+
{
|
|
1963
|
+
// We only get here if the output format is "fixed" and we just need to
|
|
1964
|
+
// round the first non-zero digit.
|
|
1965
|
+
number_of_digits -= my_exp + 1; // reset to original value
|
|
1966
|
+
if (number_of_digits)
|
|
1967
|
+
{
|
|
1968
|
+
str.insert(static_cast<std::string::size_type>(0), std::string::size_type(number_of_digits), '0');
|
|
1969
|
+
have_leading_zeros = true;
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
if (number_of_digits < 0)
|
|
1974
|
+
{
|
|
1975
|
+
str = "0";
|
|
1976
|
+
if (isneg())
|
|
1977
|
+
str.insert(static_cast<std::string::size_type>(0), 1, '-');
|
|
1978
|
+
boost::multiprecision::detail::format_float_string(str, 0, number_of_digits - my_exp - 1, f, this->iszero());
|
|
1979
|
+
return str;
|
|
1980
|
+
}
|
|
1981
|
+
else
|
|
1982
|
+
{
|
|
1983
|
+
// Cut the output to the size of the precision.
|
|
1984
|
+
if (str.length() > static_cast<std::string::size_type>(number_of_digits))
|
|
1985
|
+
{
|
|
1986
|
+
// Get the digit after the last needed digit for rounding
|
|
1987
|
+
const std::uint32_t round = static_cast<std::uint32_t>(static_cast<std::uint32_t>(str[static_cast<std::string::size_type>(number_of_digits)]) - static_cast<std::uint32_t>('0'));
|
|
1988
|
+
|
|
1989
|
+
bool need_round_up = round >= 5u;
|
|
1990
|
+
|
|
1991
|
+
if (round == 5u)
|
|
1992
|
+
{
|
|
1993
|
+
const std::uint32_t ix = number_of_digits == 0 ? 0 : static_cast<std::uint32_t>(static_cast<std::uint32_t>(str[static_cast<std::string::size_type>(number_of_digits - 1)]) - static_cast<std::uint32_t>('0'));
|
|
1994
|
+
if ((ix & 1u) == 0)
|
|
1995
|
+
{
|
|
1996
|
+
// We have an even digit followed by a 5, so we might not actually need to round up
|
|
1997
|
+
// if all the remaining digits are zero:
|
|
1998
|
+
if (str.find_first_not_of('0', static_cast<std::string::size_type>(number_of_digits + 1)) == std::string::npos)
|
|
1999
|
+
{
|
|
2000
|
+
bool all_zeros = true;
|
|
2001
|
+
// No none-zero trailing digits in the string, now check whatever parts we didn't convert to the string:
|
|
2002
|
+
for (std::size_t i = number_of_elements; i < data.size(); i++)
|
|
2003
|
+
{
|
|
2004
|
+
if (data[i])
|
|
2005
|
+
{
|
|
2006
|
+
all_zeros = false;
|
|
2007
|
+
break;
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
if (all_zeros)
|
|
2011
|
+
need_round_up = false; // tie break - round to even.
|
|
2012
|
+
}
|
|
2013
|
+
}
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
// Truncate the string
|
|
2017
|
+
str.erase(static_cast<std::string::size_type>(number_of_digits));
|
|
2018
|
+
|
|
2019
|
+
if (need_round_up)
|
|
2020
|
+
{
|
|
2021
|
+
if (str.size())
|
|
2022
|
+
{
|
|
2023
|
+
std::size_t ix = static_cast<std::size_t>(str.length() - 1u);
|
|
2024
|
+
|
|
2025
|
+
// Every trailing 9 must be rounded up
|
|
2026
|
+
while (ix && (static_cast<std::int32_t>(str.at(ix)) - static_cast<std::int32_t>('0') == static_cast<std::int32_t>(9)))
|
|
2027
|
+
{
|
|
2028
|
+
str.at(ix) = static_cast<char>('0');
|
|
2029
|
+
--ix;
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
if (!ix)
|
|
2033
|
+
{
|
|
2034
|
+
// There were nothing but trailing nines.
|
|
2035
|
+
if (static_cast<std::int32_t>(static_cast<std::int32_t>(str.at(ix)) - static_cast<std::int32_t>(0x30)) == static_cast<std::int32_t>(9))
|
|
2036
|
+
{
|
|
2037
|
+
// Increment up to the next order and adjust exponent.
|
|
2038
|
+
str.at(ix) = static_cast<char>('1');
|
|
2039
|
+
++my_exp;
|
|
2040
|
+
}
|
|
2041
|
+
else
|
|
2042
|
+
{
|
|
2043
|
+
// Round up this digit.
|
|
2044
|
+
++str.at(ix);
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2047
|
+
else
|
|
2048
|
+
{
|
|
2049
|
+
// Round up the last digit.
|
|
2050
|
+
++str[ix];
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
else
|
|
2054
|
+
{
|
|
2055
|
+
str = "1";
|
|
2056
|
+
++my_exp;
|
|
2057
|
+
}
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
if (have_leading_zeros)
|
|
2063
|
+
{
|
|
2064
|
+
// We need to take the zeros back out again, and correct the exponent
|
|
2065
|
+
// if we rounded up:
|
|
2066
|
+
if (str[std::string::size_type(number_of_digits - 1)] != '0')
|
|
2067
|
+
{
|
|
2068
|
+
++my_exp;
|
|
2069
|
+
str.erase(0, std::string::size_type(number_of_digits - 1));
|
|
2070
|
+
}
|
|
2071
|
+
else
|
|
2072
|
+
str.erase(0, std::string::size_type(number_of_digits));
|
|
2073
|
+
}
|
|
2074
|
+
|
|
2075
|
+
if (isneg())
|
|
2076
|
+
str.insert(static_cast<std::string::size_type>(0), 1, '-');
|
|
2077
|
+
|
|
2078
|
+
boost::multiprecision::detail::format_float_string(str, my_exp, org_digits, f, this->iszero());
|
|
2079
|
+
return str;
|
|
2080
|
+
}
|
|
2081
|
+
|
|
2082
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
2083
|
+
bool cpp_dec_float<Digits10, ExponentType, Allocator>::rd_string(const char* const s)
|
|
2084
|
+
{
|
|
2085
|
+
#ifndef BOOST_NO_EXCEPTIONS
|
|
2086
|
+
try
|
|
2087
|
+
{
|
|
2088
|
+
#endif
|
|
2089
|
+
|
|
2090
|
+
std::string str(s);
|
|
2091
|
+
static const std::string valid_characters{"0123456789"};
|
|
2092
|
+
|
|
2093
|
+
// TBD: Using several regular expressions may significantly reduce
|
|
2094
|
+
// the code complexity (and perhaps the run-time) of rd_string().
|
|
2095
|
+
|
|
2096
|
+
// Get a possible exponent and remove it.
|
|
2097
|
+
exp = static_cast<exponent_type>(0);
|
|
2098
|
+
|
|
2099
|
+
std::size_t pos;
|
|
2100
|
+
|
|
2101
|
+
if (((pos = str.find('e')) != std::string::npos) || ((pos = str.find('E')) != std::string::npos))
|
|
2102
|
+
{
|
|
2103
|
+
// Remove the exponent part from the string.
|
|
2104
|
+
#ifndef BOOST_MP_STANDALONE
|
|
2105
|
+
exp = boost::lexical_cast<exponent_type>(static_cast<const char*>(str.c_str() + (pos + 1u)));
|
|
2106
|
+
#else
|
|
2107
|
+
if (str.find_first_not_of(valid_characters, ((str[pos + 1] == '+') || (str[pos + 1] == '-')) ? pos + 2 : pos + 1) != std::string::npos)
|
|
2108
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Can not construct a floating point with non-numeric content"));
|
|
2109
|
+
exp = static_cast<exponent_type>(std::atoll(static_cast<const char*>(str.c_str() + (pos + 1u))));
|
|
2110
|
+
#endif
|
|
2111
|
+
|
|
2112
|
+
str = str.substr(static_cast<std::size_t>(0u), pos);
|
|
2113
|
+
}
|
|
2114
|
+
|
|
2115
|
+
// Get a possible +/- sign and remove it.
|
|
2116
|
+
neg = false;
|
|
2117
|
+
|
|
2118
|
+
if (str.size())
|
|
2119
|
+
{
|
|
2120
|
+
if (str[0] == '-')
|
|
2121
|
+
{
|
|
2122
|
+
neg = true;
|
|
2123
|
+
str.erase(0, 1);
|
|
2124
|
+
}
|
|
2125
|
+
else if (str[0] == '+')
|
|
2126
|
+
{
|
|
2127
|
+
str.erase(0, 1);
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
//
|
|
2131
|
+
// Special cases for infinities and NaN's:
|
|
2132
|
+
//
|
|
2133
|
+
if ((str == "inf") || (str == "INF") || (str == "infinity") || (str == "INFINITY"))
|
|
2134
|
+
{
|
|
2135
|
+
if (neg)
|
|
2136
|
+
{
|
|
2137
|
+
*this = this->inf();
|
|
2138
|
+
this->negate();
|
|
2139
|
+
}
|
|
2140
|
+
else
|
|
2141
|
+
*this = this->inf();
|
|
2142
|
+
return true;
|
|
2143
|
+
}
|
|
2144
|
+
if ((str.size() >= 3) && ((str.substr(0, 3) == "nan") || (str.substr(0, 3) == "NAN") || (str.substr(0, 3) == "NaN")))
|
|
2145
|
+
{
|
|
2146
|
+
*this = this->nan();
|
|
2147
|
+
return true;
|
|
2148
|
+
}
|
|
2149
|
+
|
|
2150
|
+
// Remove the leading zeros for all input types.
|
|
2151
|
+
const std::string::iterator fwd_it_leading_zero = std::find_if(str.begin(), str.end(), char_is_nonzero_predicate);
|
|
2152
|
+
|
|
2153
|
+
if (fwd_it_leading_zero != str.begin())
|
|
2154
|
+
{
|
|
2155
|
+
if (fwd_it_leading_zero == str.end())
|
|
2156
|
+
{
|
|
2157
|
+
// The string contains nothing but leading zeros.
|
|
2158
|
+
// This string represents zero.
|
|
2159
|
+
operator=(zero());
|
|
2160
|
+
return true;
|
|
2161
|
+
}
|
|
2162
|
+
else
|
|
2163
|
+
{
|
|
2164
|
+
str.erase(str.begin(), fwd_it_leading_zero);
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2168
|
+
// Put the input string into the standard cpp_dec_float<Digits10, ExponentType, Allocator> input form
|
|
2169
|
+
// aaa.bbbbE+/-n, where aaa has 1...cpp_dec_float_elem_digits10, bbbb has an
|
|
2170
|
+
// even multiple of cpp_dec_float_elem_digits10 which are possibly zero padded
|
|
2171
|
+
// on the right-end, and n is a signed 64-bit integer which is an
|
|
2172
|
+
// even multiple of cpp_dec_float_elem_digits10.
|
|
2173
|
+
|
|
2174
|
+
// Find a possible decimal point.
|
|
2175
|
+
pos = str.find(static_cast<char>('.'));
|
|
2176
|
+
|
|
2177
|
+
if (pos != std::string::npos)
|
|
2178
|
+
{
|
|
2179
|
+
// Check we have only digits either side of the point:
|
|
2180
|
+
if (str.find_first_not_of(valid_characters) != pos)
|
|
2181
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Can not construct a floating point with non-numeric content"));
|
|
2182
|
+
if (str.find_first_not_of(valid_characters, pos + 1) != std::string::npos)
|
|
2183
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Can not construct a floating point with non-numeric content"));
|
|
2184
|
+
|
|
2185
|
+
// Remove all trailing insignificant zeros.
|
|
2186
|
+
const std::string::const_reverse_iterator rit_non_zero = std::find_if(str.rbegin(), str.rend(), char_is_nonzero_predicate);
|
|
2187
|
+
|
|
2188
|
+
if (rit_non_zero != static_cast<std::string::const_reverse_iterator>(str.rbegin()))
|
|
2189
|
+
{
|
|
2190
|
+
const std::string::size_type ofs =
|
|
2191
|
+
static_cast<std::string::size_type>
|
|
2192
|
+
(
|
|
2193
|
+
static_cast<std::ptrdiff_t>(str.length())
|
|
2194
|
+
- std::distance<std::string::const_reverse_iterator>(str.rbegin(), rit_non_zero)
|
|
2195
|
+
);
|
|
2196
|
+
str.erase(str.begin() + static_cast<std::ptrdiff_t>(ofs), str.end());
|
|
2197
|
+
}
|
|
2198
|
+
|
|
2199
|
+
// Check if the input is identically zero.
|
|
2200
|
+
if (str == std::string("."))
|
|
2201
|
+
{
|
|
2202
|
+
operator=(zero());
|
|
2203
|
+
return true;
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
// Remove leading significant zeros just after the decimal point
|
|
2207
|
+
// and adjust the exponent accordingly.
|
|
2208
|
+
// Note that the while-loop operates only on strings of the form ".000abcd..."
|
|
2209
|
+
// and peels away the zeros just after the decimal point.
|
|
2210
|
+
if (str.at(static_cast<std::size_t>(0u)) == static_cast<char>('.'))
|
|
2211
|
+
{
|
|
2212
|
+
const std::string::iterator it_non_zero = std::find_if(str.begin() + 1u, str.end(), char_is_nonzero_predicate);
|
|
2213
|
+
|
|
2214
|
+
std::size_t delta_exp = static_cast<std::size_t>(0u);
|
|
2215
|
+
|
|
2216
|
+
if (str.at(static_cast<std::size_t>(1u)) == static_cast<char>('0'))
|
|
2217
|
+
{
|
|
2218
|
+
delta_exp = static_cast<std::size_t>(std::distance<std::string::const_iterator>(str.begin() + 1u, it_non_zero));
|
|
2219
|
+
}
|
|
2220
|
+
|
|
2221
|
+
// Bring one single digit into the mantissa and adjust the exponent accordingly.
|
|
2222
|
+
str.erase(str.begin(), it_non_zero);
|
|
2223
|
+
str.insert(static_cast<std::string::size_type>(1u), ".");
|
|
2224
|
+
exp -= static_cast<exponent_type>(delta_exp + 1u);
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
else
|
|
2228
|
+
{
|
|
2229
|
+
// We should have only digits:
|
|
2230
|
+
if (str.find_first_not_of(valid_characters) != std::string::npos)
|
|
2231
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Can not construct a floating point with non-numeric content"));
|
|
2232
|
+
|
|
2233
|
+
// Input string has no decimal point: Append decimal point.
|
|
2234
|
+
str.append(".");
|
|
2235
|
+
}
|
|
2236
|
+
|
|
2237
|
+
// Shift the decimal point such that the exponent is an even multiple of cpp_dec_float_elem_digits10.
|
|
2238
|
+
std::ptrdiff_t n_shift = static_cast<std::ptrdiff_t>(0);
|
|
2239
|
+
const std::ptrdiff_t n_exp_rem = static_cast<std::ptrdiff_t>(exp % static_cast<exponent_type>(cpp_dec_float_elem_digits10));
|
|
2240
|
+
|
|
2241
|
+
if((exp % static_cast<exponent_type>(cpp_dec_float_elem_digits10)) != static_cast<exponent_type>(0))
|
|
2242
|
+
{
|
|
2243
|
+
n_shift = ((exp < static_cast<exponent_type>(0))
|
|
2244
|
+
? static_cast<std::ptrdiff_t>(n_exp_rem + static_cast<std::ptrdiff_t>(cpp_dec_float_elem_digits10))
|
|
2245
|
+
: static_cast<std::ptrdiff_t>(n_exp_rem));
|
|
2246
|
+
}
|
|
2247
|
+
|
|
2248
|
+
// Make sure that there are enough digits for the decimal point shift.
|
|
2249
|
+
pos = str.find(static_cast<char>('.'));
|
|
2250
|
+
|
|
2251
|
+
std::ptrdiff_t pos_plus_one = static_cast<std::ptrdiff_t>(pos + 1);
|
|
2252
|
+
|
|
2253
|
+
if ((static_cast<std::ptrdiff_t>(str.length()) - pos_plus_one) < n_shift)
|
|
2254
|
+
{
|
|
2255
|
+
const std::ptrdiff_t sz = static_cast<std::ptrdiff_t>(n_shift - (static_cast<std::ptrdiff_t>(str.length()) - pos_plus_one));
|
|
2256
|
+
|
|
2257
|
+
str.append(std::string(static_cast<std::string::size_type>(sz), static_cast<char>('0')));
|
|
2258
|
+
}
|
|
2259
|
+
|
|
2260
|
+
// Do the decimal point shift.
|
|
2261
|
+
if (n_shift != static_cast<std::ptrdiff_t>(0))
|
|
2262
|
+
{
|
|
2263
|
+
str.insert(static_cast<std::string::size_type>(pos_plus_one + n_shift), ".");
|
|
2264
|
+
|
|
2265
|
+
str.erase(pos, static_cast<std::ptrdiff_t>(1));
|
|
2266
|
+
|
|
2267
|
+
exp -= static_cast<exponent_type>(n_shift);
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
// Cut the size of the mantissa to <= cpp_dec_float_elem_digits10.
|
|
2271
|
+
pos = str.find(static_cast<char>('.'));
|
|
2272
|
+
pos_plus_one = static_cast<std::ptrdiff_t>(pos + 1u);
|
|
2273
|
+
|
|
2274
|
+
if (pos > static_cast<std::size_t>(cpp_dec_float_elem_digits10))
|
|
2275
|
+
{
|
|
2276
|
+
const std::int32_t n_pos = static_cast<std::int32_t>(pos);
|
|
2277
|
+
const std::int32_t n_rem_is_zero = ((static_cast<std::int32_t>(n_pos % cpp_dec_float_elem_digits10) == static_cast<std::int32_t>(0)) ? static_cast<std::int32_t>(1) : static_cast<std::int32_t>(0));
|
|
2278
|
+
const std::int32_t n = static_cast<std::int32_t>(static_cast<std::int32_t>(n_pos / cpp_dec_float_elem_digits10) - n_rem_is_zero);
|
|
2279
|
+
|
|
2280
|
+
str.insert(static_cast<std::size_t>(static_cast<std::int32_t>(n_pos - static_cast<std::int32_t>(n * cpp_dec_float_elem_digits10))), ".");
|
|
2281
|
+
|
|
2282
|
+
str.erase(static_cast<std::size_t>(pos_plus_one), static_cast<std::size_t>(1u));
|
|
2283
|
+
|
|
2284
|
+
exp += static_cast<exponent_type>(static_cast<exponent_type>(n) * static_cast<exponent_type>(cpp_dec_float_elem_digits10));
|
|
2285
|
+
}
|
|
2286
|
+
|
|
2287
|
+
// Pad the decimal part such that its value is an even
|
|
2288
|
+
// multiple of cpp_dec_float_elem_digits10.
|
|
2289
|
+
pos = str.find(static_cast<char>('.'));
|
|
2290
|
+
pos_plus_one = static_cast<std::ptrdiff_t>(pos + 1u);
|
|
2291
|
+
|
|
2292
|
+
// Throws an error for a strange construction like 3.14L
|
|
2293
|
+
if(pos != std::string::npos && (str.back() == 'L' || str.back() == 'l' || str.back() == 'u' || str.back() == 'U'))
|
|
2294
|
+
{
|
|
2295
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Can not construct a floating point with an integer literal"));
|
|
2296
|
+
}
|
|
2297
|
+
|
|
2298
|
+
const std::int32_t n_dec = static_cast<std::int32_t>(static_cast<std::int32_t>(str.length() - 1u) - static_cast<std::int32_t>(pos));
|
|
2299
|
+
const std::int32_t n_rem = static_cast<std::int32_t>(n_dec % cpp_dec_float_elem_digits10);
|
|
2300
|
+
|
|
2301
|
+
std::int32_t n_cnt = ((n_rem != static_cast<std::int32_t>(0))
|
|
2302
|
+
? static_cast<std::int32_t>(cpp_dec_float_elem_digits10 - n_rem)
|
|
2303
|
+
: static_cast<std::int32_t>(0));
|
|
2304
|
+
|
|
2305
|
+
if (n_cnt != static_cast<std::int32_t>(0))
|
|
2306
|
+
{
|
|
2307
|
+
str.append(static_cast<std::size_t>(n_cnt), static_cast<char>('0'));
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
// Truncate decimal part if it is too long.
|
|
2311
|
+
const std::size_t max_dec = static_cast<std::size_t>((cpp_dec_float_elem_number - 1) * cpp_dec_float_elem_digits10);
|
|
2312
|
+
|
|
2313
|
+
if (static_cast<std::size_t>(str.length() - pos) > max_dec)
|
|
2314
|
+
{
|
|
2315
|
+
str = str.substr(static_cast<std::size_t>(0u),
|
|
2316
|
+
static_cast<std::size_t>(pos_plus_one + static_cast<std::ptrdiff_t>(max_dec)));
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2319
|
+
// Now the input string has the standard cpp_dec_float<Digits10, ExponentType, Allocator> input form.
|
|
2320
|
+
// (See the comment above.)
|
|
2321
|
+
|
|
2322
|
+
// Set all the data elements to 0.
|
|
2323
|
+
std::fill(data.begin(), data.end(), static_cast<std::uint32_t>(0u));
|
|
2324
|
+
|
|
2325
|
+
// Extract the data.
|
|
2326
|
+
|
|
2327
|
+
// First get the digits to the left of the decimal point...
|
|
2328
|
+
data[0u] = static_cast<std::uint32_t>(std::stol(str.substr(static_cast<std::size_t>(0u), pos)));
|
|
2329
|
+
|
|
2330
|
+
// ...then get the remaining digits to the right of the decimal point.
|
|
2331
|
+
const std::string::size_type i_end =
|
|
2332
|
+
(
|
|
2333
|
+
static_cast<std::string::size_type>(str.length() - static_cast<std::string::size_type>(pos_plus_one))
|
|
2334
|
+
/ static_cast<std::string::size_type>(cpp_dec_float_elem_digits10)
|
|
2335
|
+
);
|
|
2336
|
+
|
|
2337
|
+
for (std::string::size_type i = static_cast<std::string::size_type>(0u); i < i_end; i++)
|
|
2338
|
+
{
|
|
2339
|
+
const std::string::const_iterator it =
|
|
2340
|
+
str.begin()
|
|
2341
|
+
+ static_cast<std::ptrdiff_t>
|
|
2342
|
+
(
|
|
2343
|
+
static_cast<std::string::size_type>(pos_plus_one)
|
|
2344
|
+
+ static_cast<std::string::size_type>(i * static_cast<std::string::size_type>(cpp_dec_float_elem_digits10))
|
|
2345
|
+
);
|
|
2346
|
+
|
|
2347
|
+
data[i + 1u] = static_cast<std::uint32_t>(std::stol(std::string(it, it + static_cast<std::string::size_type>(cpp_dec_float_elem_digits10))));
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
// Check for overflow...
|
|
2351
|
+
if (exp > cpp_dec_float_max_exp10)
|
|
2352
|
+
{
|
|
2353
|
+
const bool b_result_is_neg = neg;
|
|
2354
|
+
|
|
2355
|
+
*this = inf();
|
|
2356
|
+
if (b_result_is_neg)
|
|
2357
|
+
negate();
|
|
2358
|
+
}
|
|
2359
|
+
|
|
2360
|
+
// ...and check for underflow.
|
|
2361
|
+
if (exp <= cpp_dec_float_min_exp10)
|
|
2362
|
+
{
|
|
2363
|
+
if (exp == cpp_dec_float_min_exp10)
|
|
2364
|
+
{
|
|
2365
|
+
// Check for identity with the minimum value.
|
|
2366
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> test = *this;
|
|
2367
|
+
|
|
2368
|
+
test.exp = static_cast<exponent_type>(0);
|
|
2369
|
+
|
|
2370
|
+
if (test.isone())
|
|
2371
|
+
{
|
|
2372
|
+
*this = zero();
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
else
|
|
2376
|
+
{
|
|
2377
|
+
*this = zero();
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
|
|
2381
|
+
#ifndef BOOST_NO_EXCEPTIONS
|
|
2382
|
+
}
|
|
2383
|
+
#ifndef BOOST_MP_STANDALONE
|
|
2384
|
+
catch (const bad_lexical_cast&)
|
|
2385
|
+
#else
|
|
2386
|
+
catch (const std::exception&)
|
|
2387
|
+
#endif
|
|
2388
|
+
{
|
|
2389
|
+
// Rethrow with better error message:
|
|
2390
|
+
std::string msg = "Unable to parse the string \"";
|
|
2391
|
+
msg += s;
|
|
2392
|
+
msg += "\" as a floating point value.";
|
|
2393
|
+
throw std::runtime_error(msg);
|
|
2394
|
+
}
|
|
2395
|
+
#endif
|
|
2396
|
+
return true;
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2399
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
2400
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float(const double mantissa, const ExponentType exponent)
|
|
2401
|
+
: data(),
|
|
2402
|
+
exp(static_cast<ExponentType>(0)),
|
|
2403
|
+
neg(false),
|
|
2404
|
+
fpclass(cpp_dec_float_finite),
|
|
2405
|
+
prec_elem(cpp_dec_float_elem_number)
|
|
2406
|
+
{
|
|
2407
|
+
// Create *this cpp_dec_float<Digits10, ExponentType, Allocator> from a given mantissa and exponent.
|
|
2408
|
+
// Note: This constructor does not maintain the full precision of double.
|
|
2409
|
+
|
|
2410
|
+
const bool mantissa_is_iszero = (::fabs(mantissa) < ((std::numeric_limits<double>::min)() * (1.0 + std::numeric_limits<double>::epsilon())));
|
|
2411
|
+
|
|
2412
|
+
if (mantissa_is_iszero)
|
|
2413
|
+
{
|
|
2414
|
+
std::fill(data.begin(), data.end(), static_cast<std::uint32_t>(0u));
|
|
2415
|
+
return;
|
|
2416
|
+
}
|
|
2417
|
+
|
|
2418
|
+
const bool b_neg = (mantissa < 0.0);
|
|
2419
|
+
|
|
2420
|
+
double d = ((!b_neg) ? mantissa : -mantissa);
|
|
2421
|
+
exponent_type e = exponent;
|
|
2422
|
+
|
|
2423
|
+
while (d > 10.0)
|
|
2424
|
+
{
|
|
2425
|
+
d /= 10.0;
|
|
2426
|
+
++e;
|
|
2427
|
+
}
|
|
2428
|
+
while (d < 1.0)
|
|
2429
|
+
{
|
|
2430
|
+
d *= 10.0;
|
|
2431
|
+
--e;
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2434
|
+
std::int32_t shift = static_cast<std::int32_t>(e % static_cast<std::int32_t>(cpp_dec_float_elem_digits10));
|
|
2435
|
+
|
|
2436
|
+
while (static_cast<std::int32_t>(shift-- % cpp_dec_float_elem_digits10) != static_cast<std::int32_t>(0))
|
|
2437
|
+
{
|
|
2438
|
+
d *= 10.0;
|
|
2439
|
+
--e;
|
|
2440
|
+
}
|
|
2441
|
+
|
|
2442
|
+
exp = e;
|
|
2443
|
+
neg = b_neg;
|
|
2444
|
+
|
|
2445
|
+
std::fill(data.begin(), data.end(), static_cast<std::uint32_t>(0u));
|
|
2446
|
+
|
|
2447
|
+
constexpr std::int32_t digit_ratio = static_cast<std::int32_t>(static_cast<std::int32_t>(std::numeric_limits<double>::digits10) / static_cast<std::int32_t>(cpp_dec_float_elem_digits10));
|
|
2448
|
+
constexpr std::int32_t digit_loops = static_cast<std::int32_t>(digit_ratio + static_cast<std::int32_t>(2));
|
|
2449
|
+
|
|
2450
|
+
for (std::int32_t i = static_cast<std::int32_t>(0); i < digit_loops; i++)
|
|
2451
|
+
{
|
|
2452
|
+
std::uint32_t n = static_cast<std::uint32_t>(static_cast<std::uint64_t>(d));
|
|
2453
|
+
data[static_cast<std::size_t>(i)] = static_cast<std::uint32_t>(n);
|
|
2454
|
+
d -= static_cast<double>(n);
|
|
2455
|
+
d *= static_cast<double>(cpp_dec_float_elem_mask);
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2458
|
+
|
|
2459
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
2460
|
+
template <class Float>
|
|
2461
|
+
typename std::enable_if<std::is_floating_point<Float>::value, cpp_dec_float<Digits10, ExponentType, Allocator>&>::type cpp_dec_float<Digits10, ExponentType, Allocator>::operator=(Float a)
|
|
2462
|
+
{
|
|
2463
|
+
// Christopher Kormanyos's original code used a cast to long long here, but that fails
|
|
2464
|
+
// when long double has more digits than a long long.
|
|
2465
|
+
BOOST_MP_FLOAT128_USING
|
|
2466
|
+
using std::floor;
|
|
2467
|
+
using std::frexp;
|
|
2468
|
+
using std::ldexp;
|
|
2469
|
+
|
|
2470
|
+
if (a == 0)
|
|
2471
|
+
return *this = zero();
|
|
2472
|
+
|
|
2473
|
+
if (a == 1)
|
|
2474
|
+
return *this = one();
|
|
2475
|
+
|
|
2476
|
+
if (BOOST_MP_ISINF(a))
|
|
2477
|
+
{
|
|
2478
|
+
*this = inf();
|
|
2479
|
+
if (a < 0)
|
|
2480
|
+
this->negate();
|
|
2481
|
+
return *this;
|
|
2482
|
+
}
|
|
2483
|
+
|
|
2484
|
+
if (BOOST_MP_ISNAN(a))
|
|
2485
|
+
return *this = nan();
|
|
2486
|
+
|
|
2487
|
+
int e;
|
|
2488
|
+
Float f, term;
|
|
2489
|
+
*this = zero();
|
|
2490
|
+
|
|
2491
|
+
f = frexp(a, &e);
|
|
2492
|
+
// See https://svn.boost.org/trac/boost/ticket/10924 for an example of why this may go wrong:
|
|
2493
|
+
BOOST_MP_ASSERT(!BOOST_MP_ISNAN(f) && !BOOST_MP_ISINF(f));
|
|
2494
|
+
|
|
2495
|
+
constexpr int shift = std::numeric_limits<int>::digits - 1;
|
|
2496
|
+
|
|
2497
|
+
while (f != static_cast<Float>(0.0f))
|
|
2498
|
+
{
|
|
2499
|
+
// extract int sized bits from f:
|
|
2500
|
+
f = ldexp(f, shift);
|
|
2501
|
+
BOOST_MP_ASSERT(!BOOST_MP_ISNAN(f) && !BOOST_MP_ISINF(f));
|
|
2502
|
+
term = floor(f);
|
|
2503
|
+
e -= shift;
|
|
2504
|
+
*this *= pow2(shift);
|
|
2505
|
+
if (term > 0)
|
|
2506
|
+
add_unsigned_long_long(static_cast<unsigned>(term));
|
|
2507
|
+
else
|
|
2508
|
+
sub_unsigned_long_long(static_cast<unsigned>(-term));
|
|
2509
|
+
f -= term;
|
|
2510
|
+
}
|
|
2511
|
+
|
|
2512
|
+
if (e != 0)
|
|
2513
|
+
*this *= pow2(e);
|
|
2514
|
+
|
|
2515
|
+
return *this;
|
|
2516
|
+
}
|
|
2517
|
+
|
|
2518
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
2519
|
+
void cpp_dec_float<Digits10, ExponentType, Allocator>::from_unsigned_long_long(const unsigned long long u)
|
|
2520
|
+
{
|
|
2521
|
+
std::fill(data.begin(), data.end(), static_cast<std::uint32_t>(0u));
|
|
2522
|
+
|
|
2523
|
+
exp = static_cast<exponent_type>(0);
|
|
2524
|
+
neg = false;
|
|
2525
|
+
fpclass = cpp_dec_float_finite;
|
|
2526
|
+
prec_elem = cpp_dec_float_elem_number;
|
|
2527
|
+
|
|
2528
|
+
if (u == 0)
|
|
2529
|
+
{
|
|
2530
|
+
return;
|
|
2531
|
+
}
|
|
2532
|
+
|
|
2533
|
+
std::size_t i = static_cast<std::size_t>(0u);
|
|
2534
|
+
|
|
2535
|
+
unsigned long long uu = u;
|
|
2536
|
+
|
|
2537
|
+
std::uint32_t temp[(std::numeric_limits<unsigned long long>::digits10 / static_cast<int>(cpp_dec_float_elem_digits10)) + 3] = {static_cast<std::uint32_t>(0u)};
|
|
2538
|
+
|
|
2539
|
+
while (uu != static_cast<unsigned long long>(0u))
|
|
2540
|
+
{
|
|
2541
|
+
temp[i] = static_cast<std::uint32_t>(uu % static_cast<unsigned long long>(cpp_dec_float_elem_mask));
|
|
2542
|
+
uu = static_cast<unsigned long long>(uu / static_cast<unsigned long long>(cpp_dec_float_elem_mask));
|
|
2543
|
+
++i;
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2546
|
+
if (i > static_cast<std::size_t>(1u))
|
|
2547
|
+
{
|
|
2548
|
+
exp += static_cast<exponent_type>((i - 1u) * static_cast<std::size_t>(cpp_dec_float_elem_digits10));
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2551
|
+
std::reverse(temp, temp + i);
|
|
2552
|
+
std::copy(temp, temp + (std::min)(i, static_cast<std::size_t>(cpp_dec_float_elem_number)), data.begin());
|
|
2553
|
+
}
|
|
2554
|
+
|
|
2555
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
2556
|
+
template <typename InputIteratorTypeLeft, typename InputIteratorTypeRight>
|
|
2557
|
+
int cpp_dec_float<Digits10, ExponentType, Allocator>::compare_ranges(InputIteratorTypeLeft a,
|
|
2558
|
+
InputIteratorTypeRight b,
|
|
2559
|
+
const std::uint32_t count)
|
|
2560
|
+
{
|
|
2561
|
+
using local_iterator_left_type = InputIteratorTypeLeft;
|
|
2562
|
+
using local_iterator_right_type = InputIteratorTypeRight;
|
|
2563
|
+
|
|
2564
|
+
local_iterator_left_type begin_a(a);
|
|
2565
|
+
local_iterator_left_type end_a (a + static_cast<typename std::iterator_traits<local_iterator_left_type >::difference_type>(count));
|
|
2566
|
+
local_iterator_right_type begin_b(b);
|
|
2567
|
+
local_iterator_right_type end_b (b + static_cast<typename std::iterator_traits<local_iterator_right_type>::difference_type>(count));
|
|
2568
|
+
|
|
2569
|
+
const auto mismatch_pair = std::mismatch(begin_a, end_a, begin_b);
|
|
2570
|
+
|
|
2571
|
+
int n_return;
|
|
2572
|
+
|
|
2573
|
+
if((mismatch_pair.first != end_a) || (mismatch_pair.second != end_b))
|
|
2574
|
+
{
|
|
2575
|
+
const typename std::iterator_traits<local_iterator_left_type >::value_type left = *mismatch_pair.first;
|
|
2576
|
+
const typename std::iterator_traits<local_iterator_right_type>::value_type right = *mismatch_pair.second;
|
|
2577
|
+
|
|
2578
|
+
n_return = ((left > right) ? 1 : -1);
|
|
2579
|
+
}
|
|
2580
|
+
else
|
|
2581
|
+
{
|
|
2582
|
+
n_return = 0;
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
return n_return;
|
|
2586
|
+
}
|
|
2587
|
+
|
|
2588
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
2589
|
+
std::uint32_t cpp_dec_float<Digits10, ExponentType, Allocator>::eval_add_n( std::uint32_t* r,
|
|
2590
|
+
const std::uint32_t* u,
|
|
2591
|
+
const std::uint32_t* v,
|
|
2592
|
+
const std::int32_t count)
|
|
2593
|
+
{
|
|
2594
|
+
// Addition algorithm
|
|
2595
|
+
std::uint_fast8_t carry = static_cast<std::uint_fast8_t>(0U);
|
|
2596
|
+
|
|
2597
|
+
for(std::int32_t j = static_cast<std::int32_t>(count - static_cast<std::int32_t>(1)); j >= static_cast<std::int32_t>(0); --j)
|
|
2598
|
+
{
|
|
2599
|
+
const std::uint32_t t = static_cast<std::uint32_t>(static_cast<std::uint32_t>(u[j] + v[j]) + carry);
|
|
2600
|
+
|
|
2601
|
+
carry = ((t >= static_cast<std::uint32_t>(cpp_dec_float_elem_mask)) ? static_cast<std::uint_fast8_t>(1U)
|
|
2602
|
+
: static_cast<std::uint_fast8_t>(0U));
|
|
2603
|
+
|
|
2604
|
+
r[j] = static_cast<std::uint32_t>(t - ((carry != 0U) ? static_cast<std::uint32_t>(cpp_dec_float_elem_mask)
|
|
2605
|
+
: static_cast<std::uint32_t>(0U)));
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
return static_cast<std::uint32_t>(carry);
|
|
2609
|
+
}
|
|
2610
|
+
|
|
2611
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
2612
|
+
std::uint32_t cpp_dec_float<Digits10, ExponentType, Allocator>::eval_subtract_n( std::uint32_t* r,
|
|
2613
|
+
const std::uint32_t* u,
|
|
2614
|
+
const std::uint32_t* v,
|
|
2615
|
+
const std::int32_t count)
|
|
2616
|
+
{
|
|
2617
|
+
// Subtraction algorithm
|
|
2618
|
+
std::int_fast8_t borrow = static_cast<std::int_fast8_t>(0);
|
|
2619
|
+
|
|
2620
|
+
for(std::uint32_t j = static_cast<std::uint32_t>(count - static_cast<std::int32_t>(1)); static_cast<std::int32_t>(j) >= static_cast<std::int32_t>(0); --j)
|
|
2621
|
+
{
|
|
2622
|
+
std::int32_t t = static_cast<std::int32_t>( static_cast<std::int32_t>(u[j])
|
|
2623
|
+
- static_cast<std::int32_t>(v[j])) - borrow;
|
|
2624
|
+
|
|
2625
|
+
// Underflow? Borrow?
|
|
2626
|
+
if(t < 0)
|
|
2627
|
+
{
|
|
2628
|
+
// Yes, underflow and borrow
|
|
2629
|
+
t += static_cast<std::int32_t>(cpp_dec_float_elem_mask);
|
|
2630
|
+
borrow = static_cast<std::int_fast8_t>(1);
|
|
2631
|
+
}
|
|
2632
|
+
else
|
|
2633
|
+
{
|
|
2634
|
+
borrow = static_cast<std::int_fast8_t>(0);
|
|
2635
|
+
}
|
|
2636
|
+
|
|
2637
|
+
r[j] = static_cast<std::uint32_t>(t);
|
|
2638
|
+
}
|
|
2639
|
+
|
|
2640
|
+
return static_cast<std::uint32_t>(borrow);
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
2644
|
+
void cpp_dec_float<Digits10, ExponentType, Allocator>::eval_multiply_n_by_n_to_2n( std::uint32_t* r,
|
|
2645
|
+
const std::uint32_t* a,
|
|
2646
|
+
const std::uint32_t* b,
|
|
2647
|
+
const std::uint32_t count)
|
|
2648
|
+
{
|
|
2649
|
+
using local_limb_type = std::uint32_t;
|
|
2650
|
+
|
|
2651
|
+
using local_double_limb_type = std::uint64_t;
|
|
2652
|
+
|
|
2653
|
+
using local_reverse_iterator_type = std::reverse_iterator<local_limb_type*>;
|
|
2654
|
+
|
|
2655
|
+
local_reverse_iterator_type ir(r + (count * 2));
|
|
2656
|
+
|
|
2657
|
+
local_double_limb_type carry = 0U;
|
|
2658
|
+
|
|
2659
|
+
for(std::int32_t j = static_cast<std::int32_t>(count - 1); j >= static_cast<std::int32_t>(1); --j)
|
|
2660
|
+
{
|
|
2661
|
+
local_double_limb_type sum = carry;
|
|
2662
|
+
|
|
2663
|
+
for(std::int32_t i = static_cast<std::int32_t>(count - 1); i >= j; --i)
|
|
2664
|
+
{
|
|
2665
|
+
sum += local_double_limb_type(
|
|
2666
|
+
local_double_limb_type(a[i]) * b[ static_cast<std::int32_t>(count - 1)
|
|
2667
|
+
- static_cast<std::int32_t>(i - j)]);
|
|
2668
|
+
}
|
|
2669
|
+
|
|
2670
|
+
carry = static_cast<local_double_limb_type>(sum / static_cast<local_limb_type> (cpp_dec_float_elem_mask));
|
|
2671
|
+
*ir++ = static_cast<local_limb_type> (sum - static_cast<local_double_limb_type>(static_cast<local_double_limb_type>(carry) * static_cast<local_limb_type>(cpp_dec_float_elem_mask)));
|
|
2672
|
+
}
|
|
2673
|
+
|
|
2674
|
+
for(std::int32_t j = static_cast<std::int32_t>(count - 1); j >= static_cast<std::int32_t>(0); --j)
|
|
2675
|
+
{
|
|
2676
|
+
local_double_limb_type sum = carry;
|
|
2677
|
+
|
|
2678
|
+
for(std::int32_t i = j; i >= static_cast<std::int32_t>(0); --i)
|
|
2679
|
+
{
|
|
2680
|
+
sum += static_cast<local_double_limb_type>(a[j - i] * static_cast<local_double_limb_type>(b[i]));
|
|
2681
|
+
}
|
|
2682
|
+
|
|
2683
|
+
carry = static_cast<local_double_limb_type>(sum / static_cast<local_limb_type>(cpp_dec_float_elem_mask));
|
|
2684
|
+
*ir++ = static_cast<local_limb_type> (sum - static_cast<local_double_limb_type>(static_cast<local_double_limb_type>(carry) * static_cast<local_limb_type>(cpp_dec_float_elem_mask)));
|
|
2685
|
+
}
|
|
2686
|
+
|
|
2687
|
+
*ir = static_cast<local_limb_type>(carry);
|
|
2688
|
+
}
|
|
2689
|
+
|
|
2690
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
2691
|
+
std::uint32_t cpp_dec_float<Digits10, ExponentType, Allocator>::mul_loop_n(std::uint32_t* const u, std::uint32_t n, const std::int32_t p)
|
|
2692
|
+
{
|
|
2693
|
+
std::uint64_t carry = static_cast<std::uint64_t>(0u);
|
|
2694
|
+
|
|
2695
|
+
// Multiplication loop.
|
|
2696
|
+
for (std::int32_t j = p - 1; j >= static_cast<std::int32_t>(0); j--)
|
|
2697
|
+
{
|
|
2698
|
+
const std::uint64_t t = static_cast<std::uint64_t>(carry + static_cast<std::uint64_t>(u[j] * static_cast<std::uint64_t>(n)));
|
|
2699
|
+
carry = static_cast<std::uint64_t>(t / static_cast<std::uint32_t>(cpp_dec_float_elem_mask));
|
|
2700
|
+
u[j] = static_cast<std::uint32_t>(t - static_cast<std::uint64_t>(static_cast<std::uint32_t>(cpp_dec_float_elem_mask) * static_cast<std::uint64_t>(carry)));
|
|
2701
|
+
}
|
|
2702
|
+
|
|
2703
|
+
return static_cast<std::uint32_t>(carry);
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
2707
|
+
std::uint32_t cpp_dec_float<Digits10, ExponentType, Allocator>::div_loop_n(std::uint32_t* const u, std::uint32_t n, const std::int32_t p)
|
|
2708
|
+
{
|
|
2709
|
+
std::uint64_t prev = static_cast<std::uint64_t>(0u);
|
|
2710
|
+
|
|
2711
|
+
for (std::int32_t j = static_cast<std::int32_t>(0); j < p; j++)
|
|
2712
|
+
{
|
|
2713
|
+
const std::uint64_t t = static_cast<std::uint64_t>(u[j] + static_cast<std::uint64_t>(prev * static_cast<std::uint32_t>(cpp_dec_float_elem_mask)));
|
|
2714
|
+
u[j] = static_cast<std::uint32_t>(t / n);
|
|
2715
|
+
prev = static_cast<std::uint64_t>(t - static_cast<std::uint64_t>(n * static_cast<std::uint64_t>(u[j])));
|
|
2716
|
+
}
|
|
2717
|
+
|
|
2718
|
+
return static_cast<std::uint32_t>(prev);
|
|
2719
|
+
}
|
|
2720
|
+
|
|
2721
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
2722
|
+
void cpp_dec_float<Digits10, ExponentType, Allocator>::eval_multiply_kara_propagate_carry(std::uint32_t* t, const std::uint32_t n, const std::uint32_t carry)
|
|
2723
|
+
{
|
|
2724
|
+
std::uint_fast8_t carry_out = ((carry != 0U) ? static_cast<std::uint_fast8_t>(1U)
|
|
2725
|
+
: static_cast<std::uint_fast8_t>(0U));
|
|
2726
|
+
|
|
2727
|
+
using local_reverse_iterator_type = std::reverse_iterator<std::uint32_t*>;
|
|
2728
|
+
|
|
2729
|
+
local_reverse_iterator_type ri_t (t + n);
|
|
2730
|
+
local_reverse_iterator_type rend_t(t);
|
|
2731
|
+
|
|
2732
|
+
while((carry_out != 0U) && (ri_t != rend_t))
|
|
2733
|
+
{
|
|
2734
|
+
const std::uint64_t tt = *ri_t + carry_out;
|
|
2735
|
+
|
|
2736
|
+
carry_out = ((tt >= static_cast<std::uint32_t>(cpp_dec_float_elem_mask)) ? static_cast<std::uint_fast8_t>(1U)
|
|
2737
|
+
: static_cast<std::uint_fast8_t>(0U));
|
|
2738
|
+
|
|
2739
|
+
*ri_t++ = static_cast<std::uint32_t>(tt - ((carry_out != 0U) ? static_cast<std::uint32_t>(cpp_dec_float_elem_mask)
|
|
2740
|
+
: static_cast<std::uint32_t>(0U)));
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
|
|
2744
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
2745
|
+
void cpp_dec_float<Digits10, ExponentType, Allocator>::eval_multiply_kara_propagate_borrow(std::uint32_t* t, const std::uint32_t n, const bool has_borrow)
|
|
2746
|
+
{
|
|
2747
|
+
std::int_fast8_t borrow = (has_borrow ? static_cast<std::int_fast8_t>(1)
|
|
2748
|
+
: static_cast<std::int_fast8_t>(0));
|
|
2749
|
+
|
|
2750
|
+
using local_reverse_iterator_type = std::reverse_iterator<std::uint32_t*>;
|
|
2751
|
+
|
|
2752
|
+
local_reverse_iterator_type ri_t (t + n);
|
|
2753
|
+
local_reverse_iterator_type rend_t(t);
|
|
2754
|
+
|
|
2755
|
+
while((borrow != 0U) && (ri_t != rend_t))
|
|
2756
|
+
{
|
|
2757
|
+
std::int32_t tt = static_cast<std::int32_t>(static_cast<std::int32_t>(*ri_t) - borrow);
|
|
2758
|
+
|
|
2759
|
+
// Underflow? Borrow?
|
|
2760
|
+
if(tt < 0)
|
|
2761
|
+
{
|
|
2762
|
+
// Yes, underflow and borrow
|
|
2763
|
+
tt += static_cast<std::int32_t>(cpp_dec_float_elem_mask);
|
|
2764
|
+
borrow = static_cast<int_fast8_t>(1);
|
|
2765
|
+
}
|
|
2766
|
+
else
|
|
2767
|
+
{
|
|
2768
|
+
borrow = static_cast<int_fast8_t>(0);
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2771
|
+
*ri_t++ = static_cast<std::uint32_t>(tt);
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
|
|
2775
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
2776
|
+
void cpp_dec_float<Digits10, ExponentType, Allocator>::eval_multiply_kara_n_by_n_to_2n( std::uint32_t* r,
|
|
2777
|
+
const std::uint32_t* a,
|
|
2778
|
+
const std::uint32_t* b,
|
|
2779
|
+
const std::uint32_t n,
|
|
2780
|
+
std::uint32_t* t)
|
|
2781
|
+
{
|
|
2782
|
+
if(n <= 32U)
|
|
2783
|
+
{
|
|
2784
|
+
static_cast<void>(t);
|
|
2785
|
+
|
|
2786
|
+
eval_multiply_n_by_n_to_2n(r, a, b, n);
|
|
2787
|
+
}
|
|
2788
|
+
else
|
|
2789
|
+
{
|
|
2790
|
+
// Based on "Algorithm 1.3 KaratsubaMultiply", Sect. 1.3.2, page 5
|
|
2791
|
+
// of R.P. Brent and P. Zimmermann, "Modern Computer Arithmetic",
|
|
2792
|
+
// Cambridge University Press (2011).
|
|
2793
|
+
|
|
2794
|
+
// The Karatsuba multipliation computes the product of a*b as:
|
|
2795
|
+
// [b^N + b^(N/2)] a1*b1 + [b^(N/2)](a1 - a0)(b0 - b1) + [b^(N/2) + 1] a0*b0
|
|
2796
|
+
|
|
2797
|
+
// Here we visualize a and b in two components 1,0 corresponding
|
|
2798
|
+
// to the high and low order parts, respectively.
|
|
2799
|
+
|
|
2800
|
+
// Step 1
|
|
2801
|
+
// Calculate a1*b1 and store it in the upper-order part of r.
|
|
2802
|
+
// Calculate a0*b0 and store it in the lower-order part of r.
|
|
2803
|
+
// copy r to t0.
|
|
2804
|
+
|
|
2805
|
+
// Step 2
|
|
2806
|
+
// Add a1*b1 (which is t2) to the middle two-quarters of r (which is r1)
|
|
2807
|
+
// Add a0*b0 (which is t0) to the middle two-quarters of r (which is r1)
|
|
2808
|
+
|
|
2809
|
+
// Step 3
|
|
2810
|
+
// Calculate |a1-a0| in t0 and note the sign (i.e., the borrow flag)
|
|
2811
|
+
|
|
2812
|
+
// Step 4
|
|
2813
|
+
// Calculate |b0-b1| in t1 and note the sign (i.e., the borrow flag)
|
|
2814
|
+
|
|
2815
|
+
// Step 5
|
|
2816
|
+
// Call kara mul to calculate |a1-a0|*|b0-b1| in (t2),
|
|
2817
|
+
// while using temporary storage in t4 along the way.
|
|
2818
|
+
|
|
2819
|
+
// Step 6
|
|
2820
|
+
// Check the borrow signs. If a1-a0 and b0-b1 have the same signs,
|
|
2821
|
+
// then add |a1-a0|*|b0-b1| to r1, otherwise subtract it from r1.
|
|
2822
|
+
|
|
2823
|
+
const std::uint_fast32_t nh = n / 2U;
|
|
2824
|
+
|
|
2825
|
+
const std::uint32_t* a0 = a + nh;
|
|
2826
|
+
const std::uint32_t* a1 = a + 0U;
|
|
2827
|
+
|
|
2828
|
+
const std::uint32_t* b0 = b + nh;
|
|
2829
|
+
const std::uint32_t* b1 = b + 0U;
|
|
2830
|
+
|
|
2831
|
+
std::uint32_t* r0 = r + 0U;
|
|
2832
|
+
std::uint32_t* r1 = r + nh;
|
|
2833
|
+
std::uint32_t* r2 = r + n;
|
|
2834
|
+
|
|
2835
|
+
std::uint32_t* t0 = t + 0U;
|
|
2836
|
+
std::uint32_t* t1 = t + nh;
|
|
2837
|
+
std::uint32_t* t2 = t + n;
|
|
2838
|
+
std::uint32_t* t4 = t + (n + n);
|
|
2839
|
+
|
|
2840
|
+
// Step 1
|
|
2841
|
+
eval_multiply_kara_n_by_n_to_2n(r0, a1, b1, static_cast<std::uint32_t>(nh), t);
|
|
2842
|
+
eval_multiply_kara_n_by_n_to_2n(r2, a0, b0, static_cast<std::uint32_t>(nh), t);
|
|
2843
|
+
std::copy(r0, r0 + (2U * n), t0);
|
|
2844
|
+
|
|
2845
|
+
// Step 2
|
|
2846
|
+
std::uint32_t carry;
|
|
2847
|
+
carry = eval_add_n(r1, r1, t0, static_cast<std::int32_t>(n));
|
|
2848
|
+
eval_multiply_kara_propagate_carry(r0, static_cast<std::uint32_t>(nh), carry);
|
|
2849
|
+
carry = eval_add_n(r1, r1, t2, static_cast<std::int32_t>(n));
|
|
2850
|
+
eval_multiply_kara_propagate_carry(r0, static_cast<std::uint32_t>(nh), carry);
|
|
2851
|
+
|
|
2852
|
+
// Step 3
|
|
2853
|
+
const int cmp_result_a1a0 = compare_ranges(a1, a0, static_cast<std::uint32_t>(nh));
|
|
2854
|
+
|
|
2855
|
+
if(cmp_result_a1a0 == 1)
|
|
2856
|
+
static_cast<void>(eval_subtract_n(t0, a1, a0, static_cast<std::int32_t>(nh)));
|
|
2857
|
+
else if(cmp_result_a1a0 == -1)
|
|
2858
|
+
static_cast<void>(eval_subtract_n(t0, a0, a1, static_cast<std::int32_t>(nh)));
|
|
2859
|
+
|
|
2860
|
+
// Step 4
|
|
2861
|
+
const int cmp_result_b0b1 = compare_ranges(b0, b1, static_cast<std::uint32_t>(nh));
|
|
2862
|
+
|
|
2863
|
+
if(cmp_result_b0b1 == 1)
|
|
2864
|
+
static_cast<void>(eval_subtract_n(t1, b0, b1, static_cast<std::int32_t>(nh)));
|
|
2865
|
+
else if(cmp_result_b0b1 == -1)
|
|
2866
|
+
static_cast<void>(eval_subtract_n(t1, b1, b0, static_cast<std::int32_t>(nh)));
|
|
2867
|
+
|
|
2868
|
+
// Step 5
|
|
2869
|
+
eval_multiply_kara_n_by_n_to_2n(t2, t0, t1, static_cast<std::uint32_t>(nh), t4);
|
|
2870
|
+
|
|
2871
|
+
// Step 6
|
|
2872
|
+
if((cmp_result_a1a0 * cmp_result_b0b1) == 1)
|
|
2873
|
+
{
|
|
2874
|
+
carry = eval_add_n(r1, r1, t2, static_cast<std::int32_t>(n));
|
|
2875
|
+
|
|
2876
|
+
eval_multiply_kara_propagate_carry(r0, static_cast<std::uint32_t>(nh), carry);
|
|
2877
|
+
}
|
|
2878
|
+
else if((cmp_result_a1a0 * cmp_result_b0b1) == -1)
|
|
2879
|
+
{
|
|
2880
|
+
const bool has_borrow = eval_subtract_n(r1, r1, t2, static_cast<std::int32_t>(n));
|
|
2881
|
+
|
|
2882
|
+
eval_multiply_kara_propagate_borrow(r0, static_cast<std::uint32_t>(nh), has_borrow);
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2885
|
+
}
|
|
2886
|
+
|
|
2887
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
2888
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(const long long p)
|
|
2889
|
+
{
|
|
2890
|
+
static const std::array<cpp_dec_float<Digits10, ExponentType, Allocator>, 256u> local_pow2_data =
|
|
2891
|
+
{{
|
|
2892
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 29u, 38735877u, 5571876u, 99218413u, 43055614u, 19454666u, 38919302u, 18803771u, 87926569u, 60431486u, 36817932u, 12890625u }, -40 ),
|
|
2893
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 58u, 77471754u, 11143753u, 98436826u, 86111228u, 38909332u, 77838604u, 37607543u, 75853139u, 20862972u, 73635864u, 25781250u }, -40 ),
|
|
2894
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 117u, 54943508u, 22287507u, 96873653u, 72222456u, 77818665u, 55677208u, 75215087u, 51706278u, 41725945u, 47271728u, 51562500u }, -40 ),
|
|
2895
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 235u, 9887016u, 44575015u, 93747307u, 44444913u, 55637331u, 11354417u, 50430175u, 3412556u, 83451890u, 94543457u, 3125000u }, -40 ),
|
|
2896
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 470u, 19774032u, 89150031u, 87494614u, 88889827u, 11274662u, 22708835u, 860350u, 6825113u, 66903781u, 89086914u, 6250000u }, -40 ),
|
|
2897
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 940u, 39548065u, 78300063u, 74989229u, 77779654u, 22549324u, 45417670u, 1720700u, 13650227u, 33807563u, 78173828u, 12500000u }, -40 ),
|
|
2898
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1880u, 79096131u, 56600127u, 49978459u, 55559308u, 45098648u, 90835340u, 3441400u, 27300454u, 67615127u, 56347656u, 25000000u }, -40 ),
|
|
2899
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 3761u, 58192263u, 13200254u, 99956919u, 11118616u, 90197297u, 81670680u, 6882800u, 54600909u, 35230255u, 12695312u, 50000000u }, -40 ),
|
|
2900
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 7523u, 16384526u, 26400509u, 99913838u, 22237233u, 80394595u, 63341360u, 13765601u, 9201818u, 70460510u, 25390625u }, -40 ),
|
|
2901
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 15046u, 32769052u, 52801019u, 99827676u, 44474467u, 60789191u, 26682720u, 27531202u, 18403637u, 40921020u, 50781250u }, -40 ),
|
|
2902
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 30092u, 65538105u, 5602039u, 99655352u, 88948935u, 21578382u, 53365440u, 55062404u, 36807274u, 81842041u, 1562500u }, -40 ),
|
|
2903
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 60185u, 31076210u, 11204079u, 99310705u, 77897870u, 43156765u, 6730881u, 10124808u, 73614549u, 63684082u, 3125000u }, -40 ),
|
|
2904
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 120370u, 62152420u, 22408159u, 98621411u, 55795740u, 86313530u, 13461762u, 20249617u, 47229099u, 27368164u, 6250000u }, -40 ),
|
|
2905
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 240741u, 24304840u, 44816319u, 97242823u, 11591481u, 72627060u, 26923524u, 40499234u, 94458198u, 54736328u, 12500000u }, -40 ),
|
|
2906
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 481482u, 48609680u, 89632639u, 94485646u, 23182963u, 45254120u, 53847048u, 80998469u, 88916397u, 9472656u, 25000000u }, -40 ),
|
|
2907
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 962964u, 97219361u, 79265279u, 88971292u, 46365926u, 90508241u, 7694097u, 61996939u, 77832794u, 18945312u, 50000000u }, -40 ),
|
|
2908
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1925929u, 94438723u, 58530559u, 77942584u, 92731853u, 81016482u, 15388195u, 23993879u, 55665588u, 37890625u }, -40 ),
|
|
2909
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 3851859u, 88877447u, 17061119u, 55885169u, 85463707u, 62032964u, 30776390u, 47987759u, 11331176u, 75781250u }, -40 ),
|
|
2910
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 7703719u, 77754894u, 34122239u, 11770339u, 70927415u, 24065928u, 61552780u, 95975518u, 22662353u, 51562500u }, -40 ),
|
|
2911
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 15407439u, 55509788u, 68244478u, 23540679u, 41854830u, 48131857u, 23105561u, 91951036u, 45324707u, 3125000u }, -40 ),
|
|
2912
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 30814879u, 11019577u, 36488956u, 47081358u, 83709660u, 96263714u, 46211123u, 83902072u, 90649414u, 6250000u }, -40 ),
|
|
2913
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 61629758u, 22039154u, 72977912u, 94162717u, 67419321u, 92527428u, 92422247u, 67804145u, 81298828u, 12500000u }, -40 ),
|
|
2914
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1u, 23259516u, 44078309u, 45955825u, 88325435u, 34838643u, 85054857u, 84844495u, 35608291u, 62597656u, 25000000u }, -32 ),
|
|
2915
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2u, 46519032u, 88156618u, 91911651u, 76650870u, 69677287u, 70109715u, 69688990u, 71216583u, 25195312u, 50000000u }, -32 ),
|
|
2916
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 4u, 93038065u, 76313237u, 83823303u, 53301741u, 39354575u, 40219431u, 39377981u, 42433166u, 50390625u }, -32 ),
|
|
2917
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 9u, 86076131u, 52626475u, 67646607u, 6603482u, 78709150u, 80438862u, 78755962u, 84866333u, 781250u }, -32 ),
|
|
2918
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 19u, 72152263u, 5252951u, 35293214u, 13206965u, 57418301u, 60877725u, 57511925u, 69732666u, 1562500u }, -32 ),
|
|
2919
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 39u, 44304526u, 10505902u, 70586428u, 26413931u, 14836603u, 21755451u, 15023851u, 39465332u, 3125000u }, -32 ),
|
|
2920
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 78u, 88609052u, 21011805u, 41172856u, 52827862u, 29673206u, 43510902u, 30047702u, 78930664u, 6250000u }, -32 ),
|
|
2921
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 157u, 77218104u, 42023610u, 82345713u, 5655724u, 59346412u, 87021804u, 60095405u, 57861328u, 12500000u }, -32 ),
|
|
2922
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 315u, 54436208u, 84047221u, 64691426u, 11311449u, 18692825u, 74043609u, 20190811u, 15722656u, 25000000u }, -32 ),
|
|
2923
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 631u, 8872417u, 68094443u, 29382852u, 22622898u, 37385651u, 48087218u, 40381622u, 31445312u, 50000000u }, -32 ),
|
|
2924
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1262u, 17744835u, 36188886u, 58765704u, 45245796u, 74771302u, 96174436u, 80763244u, 62890625u }, -32 ),
|
|
2925
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2524u, 35489670u, 72377773u, 17531408u, 90491593u, 49542605u, 92348873u, 61526489u, 25781250u }, -32 ),
|
|
2926
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 5048u, 70979341u, 44755546u, 35062817u, 80983186u, 99085211u, 84697747u, 23052978u, 51562500u }, -32 ),
|
|
2927
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 10097u, 41958682u, 89511092u, 70125635u, 61966373u, 98170423u, 69395494u, 46105957u, 3125000u }, -32 ),
|
|
2928
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 20194u, 83917365u, 79022185u, 40251271u, 23932747u, 96340847u, 38790988u, 92211914u, 6250000u }, -32 ),
|
|
2929
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 40389u, 67834731u, 58044370u, 80502542u, 47865495u, 92681694u, 77581977u, 84423828u, 12500000u }, -32 ),
|
|
2930
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 80779u, 35669463u, 16088741u, 61005084u, 95730991u, 85363389u, 55163955u, 68847656u, 25000000u }, -32 ),
|
|
2931
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 161558u, 71338926u, 32177483u, 22010169u, 91461983u, 70726779u, 10327911u, 37695312u, 50000000u }, -32 ),
|
|
2932
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 323117u, 42677852u, 64354966u, 44020339u, 82923967u, 41453558u, 20655822u, 75390625u }, -32 ),
|
|
2933
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 646234u, 85355705u, 28709932u, 88040679u, 65847934u, 82907116u, 41311645u, 50781250u }, -32 ),
|
|
2934
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1292469u, 70711410u, 57419865u, 76081359u, 31695869u, 65814232u, 82623291u, 1562500u }, -32 ),
|
|
2935
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2584939u, 41422821u, 14839731u, 52162718u, 63391739u, 31628465u, 65246582u, 3125000u }, -32 ),
|
|
2936
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 5169878u, 82845642u, 29679463u, 4325437u, 26783478u, 63256931u, 30493164u, 6250000u }, -32 ),
|
|
2937
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 10339757u, 65691284u, 59358926u, 8650874u, 53566957u, 26513862u, 60986328u, 12500000u }, -32 ),
|
|
2938
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 20679515u, 31382569u, 18717852u, 17301749u, 7133914u, 53027725u, 21972656u, 25000000u }, -32 ),
|
|
2939
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 41359030u, 62765138u, 37435704u, 34603498u, 14267829u, 6055450u, 43945312u, 50000000u }, -32 ),
|
|
2940
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 82718061u, 25530276u, 74871408u, 69206996u, 28535658u, 12110900u, 87890625u }, -32 ),
|
|
2941
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1u, 65436122u, 51060553u, 49742817u, 38413992u, 57071316u, 24221801u, 75781250u }, -24 ),
|
|
2942
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 3u, 30872245u, 2121106u, 99485634u, 76827985u, 14142632u, 48443603u, 51562500u }, -24 ),
|
|
2943
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 6u, 61744490u, 4242213u, 98971269u, 53655970u, 28285264u, 96887207u, 3125000u }, -24 ),
|
|
2944
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 13u, 23488980u, 8484427u, 97942539u, 7311940u, 56570529u, 93774414u, 6250000u }, -24 ),
|
|
2945
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 26u, 46977960u, 16968855u, 95885078u, 14623881u, 13141059u, 87548828u, 12500000u }, -24 ),
|
|
2946
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 52u, 93955920u, 33937711u, 91770156u, 29247762u, 26282119u, 75097656u, 25000000u }, -24 ),
|
|
2947
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 105u, 87911840u, 67875423u, 83540312u, 58495524u, 52564239u, 50195312u, 50000000u }, -24 ),
|
|
2948
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 211u, 75823681u, 35750847u, 67080625u, 16991049u, 5128479u, 390625u }, -24 ),
|
|
2949
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 423u, 51647362u, 71501695u, 34161250u, 33982098u, 10256958u, 781250u }, -24 ),
|
|
2950
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 847u, 3294725u, 43003390u, 68322500u, 67964196u, 20513916u, 1562500u }, -24 ),
|
|
2951
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1694u, 6589450u, 86006781u, 36645001u, 35928392u, 41027832u, 3125000u }, -24 ),
|
|
2952
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 3388u, 13178901u, 72013562u, 73290002u, 71856784u, 82055664u, 6250000u }, -24 ),
|
|
2953
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 6776u, 26357803u, 44027125u, 46580005u, 43713569u, 64111328u, 12500000u }, -24 ),
|
|
2954
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 13552u, 52715606u, 88054250u, 93160010u, 87427139u, 28222656u, 25000000u }, -24 ),
|
|
2955
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 27105u, 5431213u, 76108501u, 86320021u, 74854278u, 56445312u, 50000000u }, -24 ),
|
|
2956
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 54210u, 10862427u, 52217003u, 72640043u, 49708557u, 12890625u }, -24 ),
|
|
2957
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 108420u, 21724855u, 4434007u, 45280086u, 99417114u, 25781250u }, -24 ),
|
|
2958
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 216840u, 43449710u, 8868014u, 90560173u, 98834228u, 51562500u }, -24 ),
|
|
2959
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 433680u, 86899420u, 17736029u, 81120347u, 97668457u, 3125000u }, -24 ),
|
|
2960
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 867361u, 73798840u, 35472059u, 62240695u, 95336914u, 6250000u }, -24 ),
|
|
2961
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1734723u, 47597680u, 70944119u, 24481391u, 90673828u, 12500000u }, -24 ),
|
|
2962
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 3469446u, 95195361u, 41888238u, 48962783u, 81347656u, 25000000u }, -24 ),
|
|
2963
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 6938893u, 90390722u, 83776476u, 97925567u, 62695312u, 50000000u }, -24 ),
|
|
2964
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 13877787u, 80781445u, 67552953u, 95851135u, 25390625u }, -24 ),
|
|
2965
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 27755575u, 61562891u, 35105907u, 91702270u, 50781250u }, -24 ),
|
|
2966
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 55511151u, 23125782u, 70211815u, 83404541u, 1562500u }, -24 ),
|
|
2967
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1u, 11022302u, 46251565u, 40423631u, 66809082u, 3125000u }, -16 ),
|
|
2968
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2u, 22044604u, 92503130u, 80847263u, 33618164u, 6250000u }, -16 ),
|
|
2969
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 4u, 44089209u, 85006261u, 61694526u, 67236328u, 12500000u }, -16 ),
|
|
2970
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 8u, 88178419u, 70012523u, 23389053u, 34472656u, 25000000u }, -16 ),
|
|
2971
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 17u, 76356839u, 40025046u, 46778106u, 68945312u, 50000000u }, -16 ),
|
|
2972
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 35u, 52713678u, 80050092u, 93556213u, 37890625u }, -16 ),
|
|
2973
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 71u, 5427357u, 60100185u, 87112426u, 75781250u }, -16 ),
|
|
2974
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 142u, 10854715u, 20200371u, 74224853u, 51562500u }, -16 ),
|
|
2975
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 284u, 21709430u, 40400743u, 48449707u, 3125000u }, -16 ),
|
|
2976
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 568u, 43418860u, 80801486u, 96899414u, 6250000u }, -16 ),
|
|
2977
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1136u, 86837721u, 61602973u, 93798828u, 12500000u }, -16 ),
|
|
2978
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2273u, 73675443u, 23205947u, 87597656u, 25000000u }, -16 ),
|
|
2979
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 4547u, 47350886u, 46411895u, 75195312u, 50000000u }, -16 ),
|
|
2980
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 9094u, 94701772u, 92823791u, 50390625u }, -16 ),
|
|
2981
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 18189u, 89403545u, 85647583u, 781250u }, -16 ),
|
|
2982
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 36379u, 78807091u, 71295166u, 1562500u }, -16 ),
|
|
2983
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 72759u, 57614183u, 42590332u, 3125000u }, -16 ),
|
|
2984
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 145519u, 15228366u, 85180664u, 6250000u }, -16 ),
|
|
2985
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 291038u, 30456733u, 70361328u, 12500000u }, -16 ),
|
|
2986
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 582076u, 60913467u, 40722656u, 25000000u }, -16 ),
|
|
2987
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1164153u, 21826934u, 81445312u, 50000000u }, -16 ),
|
|
2988
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2328306u, 43653869u, 62890625u }, -16 ),
|
|
2989
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 4656612u, 87307739u, 25781250u }, -16 ),
|
|
2990
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 9313225u, 74615478u, 51562500u }, -16 ),
|
|
2991
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 18626451u, 49230957u, 3125000u }, -16 ),
|
|
2992
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 37252902u, 98461914u, 6250000u }, -16 ),
|
|
2993
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 74505805u, 96923828u, 12500000u }, -16 ),
|
|
2994
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1u, 49011611u, 93847656u, 25000000u }, -8 ),
|
|
2995
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2u, 98023223u, 87695312u, 50000000u }, -8 ),
|
|
2996
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 5u, 96046447u, 75390625u }, -8 ),
|
|
2997
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 11u, 92092895u, 50781250u }, -8 ),
|
|
2998
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 23u, 84185791u, 1562500u }, -8 ),
|
|
2999
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 47u, 68371582u, 3125000u }, -8 ),
|
|
3000
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 95u, 36743164u, 6250000u }, -8 ),
|
|
3001
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 190u, 73486328u, 12500000u }, -8 ),
|
|
3002
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 381u, 46972656u, 25000000u }, -8 ),
|
|
3003
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 762u, 93945312u, 50000000u }, -8 ),
|
|
3004
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1525u, 87890625u }, -8 ),
|
|
3005
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 3051u, 75781250u }, -8 ),
|
|
3006
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 6103u, 51562500u }, -8 ),
|
|
3007
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 12207u, 3125000u }, -8 ),
|
|
3008
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 24414u, 6250000u }, -8 ),
|
|
3009
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 48828u, 12500000u }, -8 ),
|
|
3010
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 97656u, 25000000u }, -8 ),
|
|
3011
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 195312u, 50000000u }, -8 ),
|
|
3012
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 390625u }, -8 ),
|
|
3013
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 781250u }, -8 ),
|
|
3014
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1562500u }, -8 ),
|
|
3015
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 3125000u }, -8 ),
|
|
3016
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 6250000u }, -8 ),
|
|
3017
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 12500000u }, -8 ),
|
|
3018
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 25000000u }, -8 ),
|
|
3019
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 50000000u }, -8 ),
|
|
3020
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1u }, 0 ),
|
|
3021
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2u }, 0 ),
|
|
3022
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 4u }, 0 ),
|
|
3023
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 8u }, 0 ),
|
|
3024
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 16u }, 0 ),
|
|
3025
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 32u }, 0 ),
|
|
3026
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 64u }, 0 ),
|
|
3027
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 128u }, 0 ),
|
|
3028
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 256u }, 0 ),
|
|
3029
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 512u }, 0 ),
|
|
3030
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1024u }, 0 ),
|
|
3031
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2048u }, 0 ),
|
|
3032
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 4096u }, 0 ),
|
|
3033
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 8192u }, 0 ),
|
|
3034
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 16384u }, 0 ),
|
|
3035
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 32768u }, 0 ),
|
|
3036
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 65536u }, 0 ),
|
|
3037
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 131072u }, 0 ),
|
|
3038
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 262144u }, 0 ),
|
|
3039
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 524288u }, 0 ),
|
|
3040
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1048576u }, 0 ),
|
|
3041
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2097152u }, 0 ),
|
|
3042
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 4194304u }, 0 ),
|
|
3043
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 8388608u }, 0 ),
|
|
3044
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 16777216u }, 0 ),
|
|
3045
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 33554432u }, 0 ),
|
|
3046
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 67108864u }, 0 ),
|
|
3047
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1u, 34217728u }, 8 ),
|
|
3048
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2u, 68435456u }, 8 ),
|
|
3049
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 5u, 36870912u }, 8 ),
|
|
3050
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 10u, 73741824u }, 8 ),
|
|
3051
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 21u, 47483648u }, 8 ),
|
|
3052
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 42u, 94967296u }, 8 ),
|
|
3053
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 85u, 89934592u }, 8 ),
|
|
3054
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 171u, 79869184u }, 8 ),
|
|
3055
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 343u, 59738368u }, 8 ),
|
|
3056
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 687u, 19476736u }, 8 ),
|
|
3057
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1374u, 38953472u }, 8 ),
|
|
3058
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2748u, 77906944u }, 8 ),
|
|
3059
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 5497u, 55813888u }, 8 ),
|
|
3060
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 10995u, 11627776u }, 8 ),
|
|
3061
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 21990u, 23255552u }, 8 ),
|
|
3062
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 43980u, 46511104u }, 8 ),
|
|
3063
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 87960u, 93022208u }, 8 ),
|
|
3064
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 175921u, 86044416u }, 8 ),
|
|
3065
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 351843u, 72088832u }, 8 ),
|
|
3066
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 703687u, 44177664u }, 8 ),
|
|
3067
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1407374u, 88355328u }, 8 ),
|
|
3068
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2814749u, 76710656u }, 8 ),
|
|
3069
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 5629499u, 53421312u }, 8 ),
|
|
3070
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 11258999u, 6842624u }, 8 ),
|
|
3071
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 22517998u, 13685248u }, 8 ),
|
|
3072
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 45035996u, 27370496u }, 8 ),
|
|
3073
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 90071992u, 54740992u }, 8 ),
|
|
3074
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1u, 80143985u, 9481984u }, 16 ),
|
|
3075
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 3u, 60287970u, 18963968u }, 16 ),
|
|
3076
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 7u, 20575940u, 37927936u }, 16 ),
|
|
3077
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 14u, 41151880u, 75855872u }, 16 ),
|
|
3078
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 28u, 82303761u, 51711744u }, 16 ),
|
|
3079
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 57u, 64607523u, 3423488u }, 16 ),
|
|
3080
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 115u, 29215046u, 6846976u }, 16 ),
|
|
3081
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 230u, 58430092u, 13693952u }, 16 ),
|
|
3082
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 461u, 16860184u, 27387904u }, 16 ),
|
|
3083
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 922u, 33720368u, 54775808u }, 16 ),
|
|
3084
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1844u, 67440737u, 9551616u }, 16 ),
|
|
3085
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 3689u, 34881474u, 19103232u }, 16 ),
|
|
3086
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 7378u, 69762948u, 38206464u }, 16 ),
|
|
3087
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 14757u, 39525896u, 76412928u }, 16 ),
|
|
3088
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 29514u, 79051793u, 52825856u }, 16 ),
|
|
3089
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 59029u, 58103587u, 5651712u }, 16 ),
|
|
3090
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 118059u, 16207174u, 11303424u }, 16 ),
|
|
3091
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 236118u, 32414348u, 22606848u }, 16 ),
|
|
3092
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 472236u, 64828696u, 45213696u }, 16 ),
|
|
3093
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 944473u, 29657392u, 90427392u }, 16 ),
|
|
3094
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1888946u, 59314785u, 80854784u }, 16 ),
|
|
3095
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 3777893u, 18629571u, 61709568u }, 16 ),
|
|
3096
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 7555786u, 37259143u, 23419136u }, 16 ),
|
|
3097
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 15111572u, 74518286u, 46838272u }, 16 ),
|
|
3098
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 30223145u, 49036572u, 93676544u }, 16 ),
|
|
3099
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 60446290u, 98073145u, 87353088u }, 16 ),
|
|
3100
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1u, 20892581u, 96146291u, 74706176u }, 24 ),
|
|
3101
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2u, 41785163u, 92292583u, 49412352u }, 24 ),
|
|
3102
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 4u, 83570327u, 84585166u, 98824704u }, 24 ),
|
|
3103
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 9u, 67140655u, 69170333u, 97649408u }, 24 ),
|
|
3104
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 19u, 34281311u, 38340667u, 95298816u }, 24 ),
|
|
3105
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 38u, 68562622u, 76681335u, 90597632u }, 24 ),
|
|
3106
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 77u, 37125245u, 53362671u, 81195264u }, 24 ),
|
|
3107
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 154u, 74250491u, 6725343u, 62390528u }, 24 ),
|
|
3108
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 309u, 48500982u, 13450687u, 24781056u }, 24 ),
|
|
3109
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 618u, 97001964u, 26901374u, 49562112u }, 24 ),
|
|
3110
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1237u, 94003928u, 53802748u, 99124224u }, 24 ),
|
|
3111
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2475u, 88007857u, 7605497u, 98248448u }, 24 ),
|
|
3112
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 4951u, 76015714u, 15210995u, 96496896u }, 24 ),
|
|
3113
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 9903u, 52031428u, 30421991u, 92993792u }, 24 ),
|
|
3114
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 19807u, 4062856u, 60843983u, 85987584u }, 24 ),
|
|
3115
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 39614u, 8125713u, 21687967u, 71975168u }, 24 ),
|
|
3116
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 79228u, 16251426u, 43375935u, 43950336u }, 24 ),
|
|
3117
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 158456u, 32502852u, 86751870u, 87900672u }, 24 ),
|
|
3118
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 316912u, 65005705u, 73503741u, 75801344u }, 24 ),
|
|
3119
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 633825u, 30011411u, 47007483u, 51602688u }, 24 ),
|
|
3120
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1267650u, 60022822u, 94014967u, 3205376u }, 24 ),
|
|
3121
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 2535301u, 20045645u, 88029934u, 6410752u }, 24 ),
|
|
3122
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 5070602u, 40091291u, 76059868u, 12821504u }, 24 ),
|
|
3123
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 10141204u, 80182583u, 52119736u, 25643008u }, 24 ),
|
|
3124
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 20282409u, 60365167u, 4239472u, 51286016u }, 24 ),
|
|
3125
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 40564819u, 20730334u, 8478945u, 2572032u }, 24 ),
|
|
3126
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 81129638u, 41460668u, 16957890u, 5144064u }, 24 ),
|
|
3127
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1u, 62259276u, 82921336u, 33915780u, 10288128u }, 32 ),
|
|
3128
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 3u, 24518553u, 65842672u, 67831560u, 20576256u }, 32 ),
|
|
3129
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 6u, 49037107u, 31685345u, 35663120u, 41152512u }, 32 ),
|
|
3130
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 12u, 98074214u, 63370690u, 71326240u, 82305024u }, 32 ),
|
|
3131
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 25u, 96148429u, 26741381u, 42652481u, 64610048u }, 32 ),
|
|
3132
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 51u, 92296858u, 53482762u, 85304963u, 29220096u }, 32 ),
|
|
3133
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 103u, 84593717u, 6965525u, 70609926u, 58440192u }, 32 ),
|
|
3134
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 207u, 69187434u, 13931051u, 41219853u, 16880384u }, 32 ),
|
|
3135
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 415u, 38374868u, 27862102u, 82439706u, 33760768u }, 32 ),
|
|
3136
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 830u, 76749736u, 55724205u, 64879412u, 67521536u }, 32 ),
|
|
3137
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1661u, 53499473u, 11448411u, 29758825u, 35043072u }, 32 ),
|
|
3138
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 3323u, 6998946u, 22896822u, 59517650u, 70086144u }, 32 ),
|
|
3139
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 6646u, 13997892u, 45793645u, 19035301u, 40172288u }, 32 ),
|
|
3140
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 13292u, 27995784u, 91587290u, 38070602u, 80344576u }, 32 ),
|
|
3141
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 26584u, 55991569u, 83174580u, 76141205u, 60689152u }, 32 ),
|
|
3142
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 53169u, 11983139u, 66349161u, 52282411u, 21378304u }, 32 ),
|
|
3143
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 106338u, 23966279u, 32698323u, 4564822u, 42756608u }, 32 ),
|
|
3144
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 212676u, 47932558u, 65396646u, 9129644u, 85513216u }, 32 ),
|
|
3145
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 425352u, 95865117u, 30793292u, 18259289u, 71026432u }, 32 ),
|
|
3146
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 850705u, 91730234u, 61586584u, 36518579u, 42052864u }, 32 ),
|
|
3147
|
+
cpp_dec_float<Digits10, ExponentType, Allocator>::from_lst( { 1701411u, 83460469u, 23173168u, 73037158u, 84105728u }, 32 ),
|
|
3148
|
+
}};
|
|
3149
|
+
|
|
3150
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> t;
|
|
3151
|
+
|
|
3152
|
+
if(p < -128L)
|
|
3153
|
+
default_ops::detail::pow_imp(t, cpp_dec_float<Digits10, ExponentType, Allocator>::half(), static_cast<unsigned long long>(-p), std::integral_constant<bool, false>());
|
|
3154
|
+
else if ((p >= -128L) && (p <= 127L))
|
|
3155
|
+
t = local_pow2_data[std::size_t(p + 128)];
|
|
3156
|
+
else
|
|
3157
|
+
default_ops::detail::pow_imp(t, cpp_dec_float<Digits10, ExponentType, Allocator>::two(), static_cast<unsigned long long>(p), std::integral_constant<bool, false>());
|
|
3158
|
+
|
|
3159
|
+
return t;
|
|
3160
|
+
}
|
|
3161
|
+
|
|
3162
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3163
|
+
inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& o)
|
|
3164
|
+
{
|
|
3165
|
+
result += o;
|
|
3166
|
+
}
|
|
3167
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3168
|
+
inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& o)
|
|
3169
|
+
{
|
|
3170
|
+
result -= o;
|
|
3171
|
+
}
|
|
3172
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3173
|
+
inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& o)
|
|
3174
|
+
{
|
|
3175
|
+
result *= o;
|
|
3176
|
+
}
|
|
3177
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3178
|
+
inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& o)
|
|
3179
|
+
{
|
|
3180
|
+
result /= o;
|
|
3181
|
+
}
|
|
3182
|
+
|
|
3183
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3184
|
+
inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const unsigned long long& o)
|
|
3185
|
+
{
|
|
3186
|
+
result.add_unsigned_long_long(o);
|
|
3187
|
+
}
|
|
3188
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3189
|
+
inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const unsigned long long& o)
|
|
3190
|
+
{
|
|
3191
|
+
result.sub_unsigned_long_long(o);
|
|
3192
|
+
}
|
|
3193
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3194
|
+
inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const unsigned long long& o)
|
|
3195
|
+
{
|
|
3196
|
+
result.mul_unsigned_long_long(o);
|
|
3197
|
+
}
|
|
3198
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3199
|
+
inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const unsigned long long& o)
|
|
3200
|
+
{
|
|
3201
|
+
result.div_unsigned_long_long(o);
|
|
3202
|
+
}
|
|
3203
|
+
|
|
3204
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3205
|
+
inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, long long o)
|
|
3206
|
+
{
|
|
3207
|
+
if (o < 0)
|
|
3208
|
+
result.sub_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(o));
|
|
3209
|
+
else
|
|
3210
|
+
{
|
|
3211
|
+
using local_ulonglong_type = typename boost::multiprecision::detail::make_unsigned<long long>::type;
|
|
3212
|
+
|
|
3213
|
+
result.add_unsigned_long_long(static_cast<local_ulonglong_type>(o));
|
|
3214
|
+
}
|
|
3215
|
+
}
|
|
3216
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3217
|
+
inline void eval_subtract(cpp_dec_float<Digits10, ExponentType, Allocator>& result, long long o)
|
|
3218
|
+
{
|
|
3219
|
+
if (o < 0)
|
|
3220
|
+
result.add_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(o));
|
|
3221
|
+
else
|
|
3222
|
+
{
|
|
3223
|
+
using local_ulonglong_type = typename boost::multiprecision::detail::make_unsigned<long long>::type;
|
|
3224
|
+
|
|
3225
|
+
result.sub_unsigned_long_long(static_cast<local_ulonglong_type>(o));
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3228
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3229
|
+
inline void eval_multiply(cpp_dec_float<Digits10, ExponentType, Allocator>& result, long long o)
|
|
3230
|
+
{
|
|
3231
|
+
if (o < 0)
|
|
3232
|
+
{
|
|
3233
|
+
result.mul_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(o));
|
|
3234
|
+
result.negate();
|
|
3235
|
+
}
|
|
3236
|
+
else
|
|
3237
|
+
{
|
|
3238
|
+
using local_ulonglong_type = typename boost::multiprecision::detail::make_unsigned<long long>::type;
|
|
3239
|
+
|
|
3240
|
+
result.mul_unsigned_long_long(static_cast<local_ulonglong_type>(o));
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3244
|
+
inline void eval_divide(cpp_dec_float<Digits10, ExponentType, Allocator>& result, long long o)
|
|
3245
|
+
{
|
|
3246
|
+
if (o < 0)
|
|
3247
|
+
{
|
|
3248
|
+
result.div_unsigned_long_long(boost::multiprecision::detail::unsigned_abs(o));
|
|
3249
|
+
result.negate();
|
|
3250
|
+
}
|
|
3251
|
+
else
|
|
3252
|
+
{
|
|
3253
|
+
using local_ulonglong_type = typename boost::multiprecision::detail::make_unsigned<long long>::type;
|
|
3254
|
+
|
|
3255
|
+
result.div_unsigned_long_long(static_cast<local_ulonglong_type>(o));
|
|
3256
|
+
}
|
|
3257
|
+
}
|
|
3258
|
+
|
|
3259
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3260
|
+
inline void eval_convert_to(unsigned long long* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
|
|
3261
|
+
{
|
|
3262
|
+
*result = val.extract_unsigned_long_long();
|
|
3263
|
+
}
|
|
3264
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3265
|
+
inline void eval_convert_to(long long* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
|
|
3266
|
+
{
|
|
3267
|
+
*result = val.extract_signed_long_long();
|
|
3268
|
+
}
|
|
3269
|
+
#ifdef BOOST_HAS_INT128
|
|
3270
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3271
|
+
inline void eval_convert_to(uint128_type* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
|
|
3272
|
+
{
|
|
3273
|
+
*result = val.extract_unsigned_int128();
|
|
3274
|
+
}
|
|
3275
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3276
|
+
inline void eval_convert_to(int128_type* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
|
|
3277
|
+
{
|
|
3278
|
+
*result = val.extract_signed_int128();
|
|
3279
|
+
}
|
|
3280
|
+
#endif
|
|
3281
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3282
|
+
inline void eval_convert_to(long double* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
|
|
3283
|
+
{
|
|
3284
|
+
*result = val.extract_long_double();
|
|
3285
|
+
}
|
|
3286
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3287
|
+
inline void eval_convert_to(double* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
|
|
3288
|
+
{
|
|
3289
|
+
*result = val.extract_double();
|
|
3290
|
+
}
|
|
3291
|
+
#if defined(BOOST_HAS_FLOAT128)
|
|
3292
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3293
|
+
inline void eval_convert_to(float128_type* result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
|
|
3294
|
+
{
|
|
3295
|
+
*result = float128_procs::strtoflt128(val.str(0, std::ios_base::scientific).c_str(), nullptr);
|
|
3296
|
+
}
|
|
3297
|
+
#endif
|
|
3298
|
+
|
|
3299
|
+
//
|
|
3300
|
+
// Non member function support:
|
|
3301
|
+
//
|
|
3302
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3303
|
+
inline int eval_fpclassify(const cpp_dec_float<Digits10, ExponentType, Allocator>& x)
|
|
3304
|
+
{
|
|
3305
|
+
if ((x.isinf)())
|
|
3306
|
+
return FP_INFINITE;
|
|
3307
|
+
if ((x.isnan)())
|
|
3308
|
+
return FP_NAN;
|
|
3309
|
+
if (x.iszero())
|
|
3310
|
+
return FP_ZERO;
|
|
3311
|
+
return FP_NORMAL;
|
|
3312
|
+
}
|
|
3313
|
+
|
|
3314
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3315
|
+
inline void eval_abs(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x)
|
|
3316
|
+
{
|
|
3317
|
+
result = x;
|
|
3318
|
+
if (x.isneg())
|
|
3319
|
+
result.negate();
|
|
3320
|
+
}
|
|
3321
|
+
|
|
3322
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3323
|
+
inline void eval_fabs(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x)
|
|
3324
|
+
{
|
|
3325
|
+
result = x;
|
|
3326
|
+
if (x.isneg())
|
|
3327
|
+
result.negate();
|
|
3328
|
+
}
|
|
3329
|
+
|
|
3330
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3331
|
+
inline void eval_sqrt(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x)
|
|
3332
|
+
{
|
|
3333
|
+
result = x;
|
|
3334
|
+
result.calculate_sqrt();
|
|
3335
|
+
}
|
|
3336
|
+
|
|
3337
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3338
|
+
inline void eval_floor(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x)
|
|
3339
|
+
{
|
|
3340
|
+
result = x;
|
|
3341
|
+
if (!(x.isfinite)() || x.isint())
|
|
3342
|
+
{
|
|
3343
|
+
if ((x.isnan)())
|
|
3344
|
+
errno = EDOM;
|
|
3345
|
+
return;
|
|
3346
|
+
}
|
|
3347
|
+
|
|
3348
|
+
if (x.isneg())
|
|
3349
|
+
result -= cpp_dec_float<Digits10, ExponentType, Allocator>::one();
|
|
3350
|
+
result = result.extract_integer_part();
|
|
3351
|
+
}
|
|
3352
|
+
|
|
3353
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3354
|
+
inline void eval_ceil(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x)
|
|
3355
|
+
{
|
|
3356
|
+
result = x;
|
|
3357
|
+
if (!(x.isfinite)() || x.isint())
|
|
3358
|
+
{
|
|
3359
|
+
if ((x.isnan)())
|
|
3360
|
+
errno = EDOM;
|
|
3361
|
+
return;
|
|
3362
|
+
}
|
|
3363
|
+
|
|
3364
|
+
if (!x.isneg())
|
|
3365
|
+
result += cpp_dec_float<Digits10, ExponentType, Allocator>::one();
|
|
3366
|
+
result = result.extract_integer_part();
|
|
3367
|
+
}
|
|
3368
|
+
|
|
3369
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3370
|
+
inline void eval_trunc(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x)
|
|
3371
|
+
{
|
|
3372
|
+
if (x.isint() || !(x.isfinite)())
|
|
3373
|
+
{
|
|
3374
|
+
result = x;
|
|
3375
|
+
if ((x.isnan)())
|
|
3376
|
+
errno = EDOM;
|
|
3377
|
+
return;
|
|
3378
|
+
}
|
|
3379
|
+
result = x.extract_integer_part();
|
|
3380
|
+
}
|
|
3381
|
+
|
|
3382
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3383
|
+
inline ExponentType eval_ilogb(const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
|
|
3384
|
+
{
|
|
3385
|
+
if (val.iszero())
|
|
3386
|
+
return (std::numeric_limits<typename cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type>::min)();
|
|
3387
|
+
if ((val.isinf)())
|
|
3388
|
+
return INT_MAX;
|
|
3389
|
+
if ((val.isnan)())
|
|
3390
|
+
#ifdef FP_ILOGBNAN
|
|
3391
|
+
return FP_ILOGBNAN;
|
|
3392
|
+
#else
|
|
3393
|
+
return INT_MAX;
|
|
3394
|
+
#endif
|
|
3395
|
+
// Set result, to the exponent of val:
|
|
3396
|
+
return val.order();
|
|
3397
|
+
}
|
|
3398
|
+
template <unsigned Digits10, class ExponentType, class Allocator, class ArgType>
|
|
3399
|
+
inline void eval_scalbn(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& val, ArgType e_)
|
|
3400
|
+
{
|
|
3401
|
+
using default_ops::eval_multiply;
|
|
3402
|
+
const typename cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type e = static_cast<typename cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type>(e_);
|
|
3403
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> t(1.0, e);
|
|
3404
|
+
eval_multiply(result, val, t);
|
|
3405
|
+
}
|
|
3406
|
+
|
|
3407
|
+
template <unsigned Digits10, class ExponentType, class Allocator, class ArgType>
|
|
3408
|
+
inline void eval_ldexp(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x, ArgType e)
|
|
3409
|
+
{
|
|
3410
|
+
const long long the_exp = static_cast<long long>(e);
|
|
3411
|
+
|
|
3412
|
+
if ((the_exp > (std::numeric_limits<typename cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type>::max)()) || (the_exp < (std::numeric_limits<typename cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type>::min)()))
|
|
3413
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error(std::string("Exponent value is out of range.")));
|
|
3414
|
+
|
|
3415
|
+
result = x;
|
|
3416
|
+
|
|
3417
|
+
if ((the_exp > static_cast<long long>(-std::numeric_limits<long long>::digits)) && (the_exp < static_cast<long long>(0)))
|
|
3418
|
+
result.div_unsigned_long_long(1ULL << static_cast<long long>(-the_exp));
|
|
3419
|
+
else if ((the_exp < static_cast<long long>(std::numeric_limits<long long>::digits)) && (the_exp > static_cast<long long>(0)))
|
|
3420
|
+
result.mul_unsigned_long_long(1ULL << the_exp);
|
|
3421
|
+
else if (the_exp != static_cast<long long>(0))
|
|
3422
|
+
{
|
|
3423
|
+
if ((the_exp < cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp / 2) && (x.order() > 0))
|
|
3424
|
+
{
|
|
3425
|
+
long long half_exp = e / 2;
|
|
3426
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> t = cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(half_exp);
|
|
3427
|
+
result *= t;
|
|
3428
|
+
if (2 * half_exp != e)
|
|
3429
|
+
t *= 2;
|
|
3430
|
+
result *= t;
|
|
3431
|
+
}
|
|
3432
|
+
else
|
|
3433
|
+
result *= cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(e);
|
|
3434
|
+
}
|
|
3435
|
+
}
|
|
3436
|
+
|
|
3437
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3438
|
+
inline void eval_frexp(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x, ExponentType* e)
|
|
3439
|
+
{
|
|
3440
|
+
result = x;
|
|
3441
|
+
|
|
3442
|
+
if (result.iszero() || (result.isinf)() || (result.isnan)())
|
|
3443
|
+
{
|
|
3444
|
+
*e = 0;
|
|
3445
|
+
return;
|
|
3446
|
+
}
|
|
3447
|
+
|
|
3448
|
+
if (result.isneg())
|
|
3449
|
+
result.negate();
|
|
3450
|
+
|
|
3451
|
+
typename cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type t = result.order();
|
|
3452
|
+
BOOST_MP_USING_ABS
|
|
3453
|
+
if (abs(t) < ((std::numeric_limits<typename cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type>::max)() / 1000))
|
|
3454
|
+
{
|
|
3455
|
+
t *= 1000;
|
|
3456
|
+
t /= 301;
|
|
3457
|
+
}
|
|
3458
|
+
else
|
|
3459
|
+
{
|
|
3460
|
+
t /= 301;
|
|
3461
|
+
t *= 1000;
|
|
3462
|
+
}
|
|
3463
|
+
|
|
3464
|
+
result *= cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(-t);
|
|
3465
|
+
|
|
3466
|
+
if (result.iszero() || (result.isinf)() || (result.isnan)())
|
|
3467
|
+
{
|
|
3468
|
+
// pow2 overflowed, slip the calculation up:
|
|
3469
|
+
result = x;
|
|
3470
|
+
if (result.isneg())
|
|
3471
|
+
result.negate();
|
|
3472
|
+
t /= 2;
|
|
3473
|
+
result *= cpp_dec_float<Digits10, ExponentType, Allocator>::pow2(-t);
|
|
3474
|
+
}
|
|
3475
|
+
BOOST_MP_USING_ABS
|
|
3476
|
+
if (abs(result.order()) > 5)
|
|
3477
|
+
{
|
|
3478
|
+
// If our first estimate doesn't get close enough then try recursion until we do:
|
|
3479
|
+
typename cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type e2;
|
|
3480
|
+
cpp_dec_float<Digits10, ExponentType, Allocator> r2;
|
|
3481
|
+
eval_frexp(r2, result, &e2);
|
|
3482
|
+
// overflow protection:
|
|
3483
|
+
if ((t > 0) && (e2 > 0) && (t > (std::numeric_limits<typename cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type>::max)() - e2))
|
|
3484
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Exponent is too large to be represented as a power of 2."));
|
|
3485
|
+
if ((t < 0) && (e2 < 0) && (t < (std::numeric_limits<typename cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type>::min)() - e2))
|
|
3486
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Exponent is too large to be represented as a power of 2."));
|
|
3487
|
+
t += e2;
|
|
3488
|
+
result = r2;
|
|
3489
|
+
}
|
|
3490
|
+
|
|
3491
|
+
while (result.compare(cpp_dec_float<Digits10, ExponentType, Allocator>::one()) >= 0)
|
|
3492
|
+
{
|
|
3493
|
+
result /= cpp_dec_float<Digits10, ExponentType, Allocator>::two();
|
|
3494
|
+
++t;
|
|
3495
|
+
}
|
|
3496
|
+
while (result.compare(cpp_dec_float<Digits10, ExponentType, Allocator>::half()) < 0)
|
|
3497
|
+
{
|
|
3498
|
+
result *= cpp_dec_float<Digits10, ExponentType, Allocator>::two();
|
|
3499
|
+
--t;
|
|
3500
|
+
}
|
|
3501
|
+
*e = t;
|
|
3502
|
+
if (x.isneg())
|
|
3503
|
+
result.negate();
|
|
3504
|
+
}
|
|
3505
|
+
|
|
3506
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3507
|
+
inline typename std::enable_if< !std::is_same<ExponentType, int>::value>::type eval_frexp(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& x, int* e)
|
|
3508
|
+
{
|
|
3509
|
+
typename cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type t;
|
|
3510
|
+
eval_frexp(result, x, &t);
|
|
3511
|
+
if ((t > (std::numeric_limits<int>::max)()) || (t < (std::numeric_limits<int>::min)()))
|
|
3512
|
+
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Exponent is outside the range of an int"));
|
|
3513
|
+
*e = static_cast<int>(t);
|
|
3514
|
+
}
|
|
3515
|
+
|
|
3516
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3517
|
+
inline bool eval_is_zero(const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
|
|
3518
|
+
{
|
|
3519
|
+
return val.iszero();
|
|
3520
|
+
}
|
|
3521
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3522
|
+
inline int eval_get_sign(const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
|
|
3523
|
+
{
|
|
3524
|
+
return val.iszero() ? 0 : val.isneg() ? -1 : 1;
|
|
3525
|
+
}
|
|
3526
|
+
|
|
3527
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3528
|
+
inline std::size_t hash_value(const cpp_dec_float<Digits10, ExponentType, Allocator>& val)
|
|
3529
|
+
{
|
|
3530
|
+
return val.hash();
|
|
3531
|
+
}
|
|
3532
|
+
|
|
3533
|
+
} // namespace backends
|
|
3534
|
+
|
|
3535
|
+
namespace detail {
|
|
3536
|
+
|
|
3537
|
+
template <unsigned Digits10, class ExponentType, class Allocator>
|
|
3538
|
+
struct transcendental_reduction_type<boost::multiprecision::backends::cpp_dec_float<Digits10, ExponentType, Allocator> >
|
|
3539
|
+
{
|
|
3540
|
+
//
|
|
3541
|
+
// The type used for trigonometric reduction needs 3 times the precision of the base type.
|
|
3542
|
+
// This is double the precision of the original type, plus the largest exponent supported.
|
|
3543
|
+
// As a practical measure the largest argument supported is 1/eps, as supporting larger
|
|
3544
|
+
// arguments requires the division of argument by PI/2 to also be done at higher precision,
|
|
3545
|
+
// otherwise the result (an integer) can not be represented exactly.
|
|
3546
|
+
//
|
|
3547
|
+
// See ARGUMENT REDUCTION FOR HUGE ARGUMENTS. K C Ng.
|
|
3548
|
+
//
|
|
3549
|
+
using type = boost::multiprecision::backends::cpp_dec_float<Digits10 * 3, ExponentType, Allocator>;
|
|
3550
|
+
};
|
|
3551
|
+
|
|
3552
|
+
} // namespace detail
|
|
3553
|
+
|
|
3554
|
+
|
|
3555
|
+
}} // namespace boost::multiprecision
|
|
3556
|
+
|
|
3557
|
+
namespace std {
|
|
3558
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3559
|
+
class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >
|
|
3560
|
+
{
|
|
3561
|
+
public:
|
|
3562
|
+
static constexpr bool is_specialized = true;
|
|
3563
|
+
static constexpr bool is_signed = true;
|
|
3564
|
+
static constexpr bool is_integer = false;
|
|
3565
|
+
static constexpr bool is_exact = false;
|
|
3566
|
+
static constexpr bool is_bounded = true;
|
|
3567
|
+
static constexpr bool is_modulo = false;
|
|
3568
|
+
static constexpr bool is_iec559 = false;
|
|
3569
|
+
static constexpr int digits = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10;
|
|
3570
|
+
static constexpr int digits10 = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10;
|
|
3571
|
+
static constexpr int max_digits10 = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_digits10;
|
|
3572
|
+
static constexpr typename boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type min_exponent = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp; // Type differs from int.
|
|
3573
|
+
static constexpr typename boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type min_exponent10 = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_min_exp10; // Type differs from int.
|
|
3574
|
+
static constexpr typename boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type max_exponent = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_exp; // Type differs from int.
|
|
3575
|
+
static constexpr typename boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type max_exponent10 = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_max_exp10; // Type differs from int.
|
|
3576
|
+
static constexpr int radix = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_radix;
|
|
3577
|
+
static constexpr std::float_round_style round_style = std::round_indeterminate;
|
|
3578
|
+
static constexpr bool has_infinity = true;
|
|
3579
|
+
static constexpr bool has_quiet_NaN = true;
|
|
3580
|
+
static constexpr bool has_signaling_NaN = false;
|
|
3581
|
+
#ifdef _MSC_VER
|
|
3582
|
+
#pragma warning(push)
|
|
3583
|
+
#pragma warning(disable : 4996)
|
|
3584
|
+
#endif
|
|
3585
|
+
static constexpr std::float_denorm_style has_denorm = std::denorm_absent;
|
|
3586
|
+
#ifdef _MSC_VER
|
|
3587
|
+
#pragma warning(pop)
|
|
3588
|
+
#endif
|
|
3589
|
+
static constexpr bool has_denorm_loss = false;
|
|
3590
|
+
static constexpr bool traps = false;
|
|
3591
|
+
static constexpr bool tinyness_before = false;
|
|
3592
|
+
|
|
3593
|
+
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates>(min)() { return (boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::min)(); }
|
|
3594
|
+
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates>(max)() { return (boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::max)(); }
|
|
3595
|
+
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> lowest() { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::zero(); }
|
|
3596
|
+
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> epsilon() { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::eps(); }
|
|
3597
|
+
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> round_error() { return 0.5L; }
|
|
3598
|
+
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> infinity() { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::inf(); }
|
|
3599
|
+
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> quiet_NaN() { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::nan(); }
|
|
3600
|
+
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> signaling_NaN() { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::zero(); }
|
|
3601
|
+
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> denorm_min() { return (boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::min)(); }
|
|
3602
|
+
};
|
|
3603
|
+
|
|
3604
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3605
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::digits;
|
|
3606
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3607
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::digits10;
|
|
3608
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3609
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::max_digits10;
|
|
3610
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3611
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_signed;
|
|
3612
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3613
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_integer;
|
|
3614
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3615
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_exact;
|
|
3616
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3617
|
+
constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::radix;
|
|
3618
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3619
|
+
constexpr typename boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::min_exponent;
|
|
3620
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3621
|
+
constexpr typename boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::min_exponent10;
|
|
3622
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3623
|
+
constexpr typename boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::max_exponent;
|
|
3624
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3625
|
+
constexpr typename boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::exponent_type numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::max_exponent10;
|
|
3626
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3627
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::has_infinity;
|
|
3628
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3629
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::has_quiet_NaN;
|
|
3630
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3631
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::has_signaling_NaN;
|
|
3632
|
+
#ifdef _MSC_VER
|
|
3633
|
+
#pragma warning(push)
|
|
3634
|
+
#pragma warning(disable : 4996)
|
|
3635
|
+
#endif
|
|
3636
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3637
|
+
constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::has_denorm;
|
|
3638
|
+
#ifdef _MSC_VER
|
|
3639
|
+
#pragma warning(pop)
|
|
3640
|
+
#endif
|
|
3641
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3642
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::has_denorm_loss;
|
|
3643
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3644
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_iec559;
|
|
3645
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3646
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_bounded;
|
|
3647
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3648
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::is_modulo;
|
|
3649
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3650
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::traps;
|
|
3651
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3652
|
+
constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::tinyness_before;
|
|
3653
|
+
template <unsigned Digits10, class ExponentType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3654
|
+
constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> >::round_style;
|
|
3655
|
+
|
|
3656
|
+
} // namespace std
|
|
3657
|
+
|
|
3658
|
+
#ifdef BOOST_MP_MATH_AVAILABLE
|
|
3659
|
+
namespace boost {
|
|
3660
|
+
namespace math {
|
|
3661
|
+
|
|
3662
|
+
namespace policies {
|
|
3663
|
+
|
|
3664
|
+
template <unsigned Digits10, class ExponentType, class Allocator, class Policy, boost::multiprecision::expression_template_option ExpressionTemplates>
|
|
3665
|
+
struct precision<boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates>, Policy>
|
|
3666
|
+
{
|
|
3667
|
+
// Define a local copy of cpp_dec_float_digits10 because it might differ
|
|
3668
|
+
// from the template parameter Digits10 for small or large digit counts.
|
|
3669
|
+
static constexpr std::int32_t cpp_dec_float_digits10 = boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::cpp_dec_float_digits10;
|
|
3670
|
+
|
|
3671
|
+
using precision_type = typename Policy::precision_type ;
|
|
3672
|
+
using digits_2 = digits2<static_cast<int>(((cpp_dec_float_digits10 + 1LL) * 1000LL) / 301LL)>;
|
|
3673
|
+
using type = typename std::conditional<
|
|
3674
|
+
((digits_2::value <= precision_type::value) || (Policy::precision_type::value <= 0)),
|
|
3675
|
+
// Default case, full precision for RealType:
|
|
3676
|
+
digits_2,
|
|
3677
|
+
// User customized precision:
|
|
3678
|
+
precision_type>::type;
|
|
3679
|
+
};
|
|
3680
|
+
|
|
3681
|
+
}
|
|
3682
|
+
|
|
3683
|
+
}} // namespace boost::math::policies
|
|
3684
|
+
#endif
|
|
3685
|
+
|
|
3686
|
+
#ifdef BOOST_MSVC
|
|
3687
|
+
#pragma warning(pop)
|
|
3688
|
+
#endif
|
|
3689
|
+
|
|
3690
|
+
#endif
|