Skip to content

Commit

Permalink
Merge pull request #296 from bluescarni/pr/real_iter
Browse files Browse the repository at this point in the history
API additions
  • Loading branch information
bluescarni authored Oct 21, 2022
2 parents 8bd5a9f + 0e705f9 commit 4eab53d
Show file tree
Hide file tree
Showing 36 changed files with 946 additions and 230 deletions.
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ option(MPPP_WITH_ARB "Enable features relying on Arb." OFF)
option(MPPP_WITH_MPC "Enable features relying on MPC." OFF)
option(MPPP_WITH_QUADMATH "Enable features relying on libquadmath (e.g., the real128 type)." OFF)
option(MPPP_WITH_BOOST_S11N "Enable features relying on the Boost.Serialization library." OFF)
option(MPPP_WITH_FMT "Enable support for the fmt library." OFF)
option(MPPP_TEST_PYBIND11 "Build tests for the pybind11 integration utilities (effective only if MPPP_BUILD_TESTS is TRUE, requires pybind11 and Python).")
mark_as_advanced(MPPP_TEST_PYBIND11)
option(MPPP_BUILD_STATIC_LIBRARY "Build mp++ as a static library, instead of dynamic." OFF)
Expand Down Expand Up @@ -411,6 +412,15 @@ if(MPPP_WITH_BOOST_S11N)
target_link_libraries(mp++ PUBLIC Boost::serialization Boost::disable_autolinking)
endif()

# NOTE: need at least version 6.2
# to print 128-bit integers.
set(_MPPP_MIN_FMT_VERSION "6.2")
if(MPPP_WITH_FMT)
find_package(fmt ${_MPPP_MIN_FMT_VERSION} REQUIRED CONFIG)
message(STATUS "fmt version: ${fmt_VERSION}")
target_link_libraries(mp++ PUBLIC fmt::fmt)
endif()

# Mandatory dependency on GMP.
# NOTE: depend on GMP *after* optionally depending on MPFR, as the order
# of the libraries matters on some platforms.
Expand Down Expand Up @@ -478,3 +488,4 @@ if(MPPP_BUILD_BENCHMARKS)
endif()

unset(_MPPP_MIN_BOOST_VERSION)
unset(_MPPP_MIN_FMT_VERSION)
18 changes: 5 additions & 13 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ install:
- if [%BUILD_TYPE%]==[MSVC15_64] conda update -n base conda
- if [%BUILD_TYPE%]==[MSVC15_64] conda config --add channels conda-forge
- if [%BUILD_TYPE%]==[MSVC15_64] conda config --set channel_priority strict
- if [%BUILD_TYPE%]==[MSVC15_64] conda create --name mppp cmake mpir mpfr mpc arb pybind11 mpmath python=3.6 boost-cpp
- if [%BUILD_TYPE%]==[MSVC15_64] conda create --name mppp cmake mpir mpfr mpc arb boost-cpp
- if [%BUILD_TYPE%]==[MSVC15_64] call activate mppp

- if [%BUILD_TYPE%]==[MSVC17_64] call "C:\\Miniconda37-x64\\Scripts\\activate.bat"
- if [%BUILD_TYPE%]==[MSVC17_64] conda config --set always_yes yes
- if [%BUILD_TYPE%]==[MSVC17_64] conda update -n base conda
- if [%BUILD_TYPE%]==[MSVC17_64] conda config --add channels conda-forge
- if [%BUILD_TYPE%]==[MSVC17_64] conda config --set channel_priority strict
- if [%BUILD_TYPE%]==[MSVC17_64] conda create --name mppp cmake mpir mpfr mpc arb pybind11 mpmath python=3.6 boost-cpp
- if [%BUILD_TYPE%]==[MSVC17_64] conda create --name mppp cmake mpir mpfr mpc arb boost-cpp fmt
- if [%BUILD_TYPE%]==[MSVC17_64] call activate mppp

- if [%BUILD_TYPE%]==[MSVC15_clang_64] call "C:\\Miniconda37-x64\\Scripts\\activate.bat"
Expand Down Expand Up @@ -65,14 +65,10 @@ build_script:

- if [%BUILD_TYPE%]==[MSVC15_64] cmake .. -G "Visual Studio 14 2015 Win64" -DMPPP_BUILD_TESTS=yes -DBoost_NO_BOOST_CMAKE=ON -DMPPP_WITH_BOOST_S11N=yes -DMPPP_WITH_MPFR=yes -DMPPP_WITH_MPC=yes -DMPPP_WITH_ARB=yes -DMPPP_ENABLE_IPO=yes
- if [%BUILD_TYPE%]==[MSVC15_64] cmake --build . --config Release
- if [%BUILD_TYPE%]==[MSVC15_64] cmake .. -G "Visual Studio 14 2015 Win64" -DMPPP_BUILD_TESTS=yes -DBoost_NO_BOOST_CMAKE=ON -DMPPP_WITH_BOOST_S11N=yes -DMPPP_WITH_MPFR=yes -DMPPP_WITH_MPC=yes -DMPPP_WITH_ARB=yes -DMPPP_TEST_PYBIND11=yes -DMPPP_ENABLE_IPO=yes
- if [%BUILD_TYPE%]==[MSVC15_64] cmake --build . --config Release --target pybind11_test_01

# This build enables Unicode solutions.
- if [%BUILD_TYPE%]==[MSVC17_64] cmake .. -G "Visual Studio 15 2017 Win64" -DMPPP_BUILD_TESTS=yes -DBoost_NO_BOOST_CMAKE=ON -DMPPP_WITH_BOOST_S11N=yes -DMPPP_WITH_MPFR=yes -DMPPP_WITH_MPC=yes -DMPPP_WITH_ARB=yes -DCMAKE_CXX_STANDARD=17 -DMPPP_MSVC_UNICODE=YES -DMPPP_ENABLE_IPO=yes
- if [%BUILD_TYPE%]==[MSVC17_64] cmake .. -G "Visual Studio 15 2017 Win64" -DMPPP_BUILD_TESTS=yes -DBoost_NO_BOOST_CMAKE=ON -DMPPP_WITH_BOOST_S11N=yes -DMPPP_WITH_FMT=yes -DMPPP_WITH_MPFR=yes -DMPPP_WITH_MPC=yes -DMPPP_WITH_ARB=yes -DCMAKE_CXX_STANDARD=17 -DMPPP_MSVC_UNICODE=YES -DMPPP_ENABLE_IPO=yes
- if [%BUILD_TYPE%]==[MSVC17_64] cmake --build . --config Release
- if [%BUILD_TYPE%]==[MSVC17_64] cmake .. -G "Visual Studio 15 2017 Win64" -DMPPP_BUILD_TESTS=yes -DBoost_NO_BOOST_CMAKE=ON -DMPPP_WITH_BOOST_S11N=yes -DMPPP_WITH_MPFR=yes -DMPPP_WITH_MPC=yes -DMPPP_WITH_ARB=yes -DMPPP_TEST_PYBIND11=yes -DCMAKE_CXX_STANDARD=17 -DMPPP_MSVC_UNICODE=YES -DMPPP_ENABLE_IPO=yes
- if [%BUILD_TYPE%]==[MSVC17_64] cmake --build . --config Release --target pybind11_test_01

- if [%BUILD_TYPE%]==[MSVC15_clang_64] cmake .. -GNinja -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_C_COMPILER=clang-cl -DCMAKE_BUILD_TYPE=Debug -DMPPP_BUILD_TESTS=yes -DMPPP_WITH_MPFR=yes -DMPPP_WITH_MPC=yes -DMPPP_WITH_ARB=yes -DMPPP_BUILD_STATIC_LIBRARY=yes -DCMAKE_CXX_STANDARD=17 -DMPPP_ENABLE_IPO=yes
- if [%BUILD_TYPE%]==[MSVC15_clang_64] cmake --build . -- -v
Expand All @@ -87,15 +83,11 @@ test_script:

- if [%BUILD_TYPE%]==[MSVC15_64] set OLD_PATH=%PATH%
- if [%BUILD_TYPE%]==[MSVC15_64] set PATH=%PATH%;%CD%\Release
- if [%BUILD_TYPE%]==[MSVC15_64] ctest -V -C Release -E pybind11
- if [%BUILD_TYPE%]==[MSVC15_64] set PATH=%OLD_PATH%;%CD%\Release
- if [%BUILD_TYPE%]==[MSVC15_64] ctest -V -C Release -R pybind11
- if [%BUILD_TYPE%]==[MSVC15_64] ctest -V -C Release

- if [%BUILD_TYPE%]==[MSVC17_64] set OLD_PATH=%PATH%
- if [%BUILD_TYPE%]==[MSVC17_64] set PATH=%PATH%;%CD%\Release
- if [%BUILD_TYPE%]==[MSVC17_64] ctest -V -C Release -E pybind11
- if [%BUILD_TYPE%]==[MSVC17_64] set PATH=%OLD_PATH%;%CD%\Release
- if [%BUILD_TYPE%]==[MSVC17_64] ctest -V -C Release -R pybind11
- if [%BUILD_TYPE%]==[MSVC17_64] ctest -V -C Release

# NOTE: no need to alter the PATH, static library build.
- if [%BUILD_TYPE%]==[MSVC15_clang_64] ctest -V
Expand Down
4 changes: 1 addition & 3 deletions benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ if(NOT TARGET Boost::boost)
endif()

# fmt is always required.
# NOTE: need at least version 6.2
# to print 128-bit integers.
find_package(fmt 6.2 REQUIRED)
find_package(fmt ${_MPPP_MIN_FMT_VERSION} REQUIRED CONFIG)

if(MPPP_BENCHMARK_FLINT)
find_package(mp++_FLINT REQUIRED)
Expand Down
1 change: 1 addition & 0 deletions config.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#cmakedefine MPPP_QUADMATH_HAVE_LOGBQ
@MPPP_STATIC_BUILD@
#cmakedefine MPPP_WITH_BOOST_S11N
#cmakedefine MPPP_WITH_FMT
// clang-format on
// End of defines instantiated by CMake.

Expand Down
5 changes: 5 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ Changelog
New
~~~

- Add initial optional support for formatting via the fmt library
(`#296 <https://github.com/bluescarni/mppp/pull/296>`__).
- Add helpers to determine the number of limbs in the significand
of a :cpp:class:`~mppp::real` number
(`#296 <https://github.com/bluescarni/mppp/pull/296>`__).
- Add several ``std`` math overloads for :cpp:class:`~mppp::real`
(`#295 <https://github.com/bluescarni/mppp/pull/295>`__).
- Add hashing capabilities to :cpp:class:`~mppp::real`
Expand Down
23 changes: 23 additions & 0 deletions doc/definitions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,36 @@ Macros and definitions
This name is defined if mp++ was configured with support for the quadmath library
(see the :ref:`installation instructions <installation>`).

.. c:macro:: MPPP_QUADMATH_HAVE_EXP2Q
.. versionadded:: 0.27

This name is defined if mp++ was configured with support for a quadmath library version
providing the ``exp2q()`` function
(see the :ref:`installation instructions <installation>`).

.. c:macro:: MPPP_QUADMATH_HAVE_LOGBQ
.. versionadded:: 0.27

This name is defined if mp++ was configured with support for a quadmath library version
providing the ``logbq()`` function
(see the :ref:`installation instructions <installation>`).

.. c:macro:: MPPP_WITH_BOOST_S11N
.. versionadded:: 0.22

This name is defined if mp++ was configured with support for the Boost.serialization library
(see the :ref:`installation instructions <installation>`).

.. c:macro:: MPPP_WITH_FMT
.. versionadded:: 0.27

This name is defined if mp++ was configured with support for the fmt library
(see the :ref:`installation instructions <installation>`).

.. c:macro:: MPPP_FLOAT128_WITH_LONG_DOUBLE
.. versionadded:: 0.22
Expand Down
13 changes: 10 additions & 3 deletions doc/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ mp++ has the following dependencies:
be installed separately);
* the `Boost <https://www.boost.org/>`__ libraries, *optional*, currently used
for implementing (de)serialisation and in the benchmarking suite;
* the `{fmt} <https://fmt.dev/latest/index.html>`__ library (at least version 6.2), *optional*, currently used
only in the benchmarking suite.
* the `{fmt} <https://fmt.dev/latest/index.html>`__ library (at least version 6.2), *optional*, used
to provide formatting capabilities to the multiprecision classes and in the benchmarking suite.

Additionally, `CMake <https://cmake.org/>`__ is the build system used by mp++ and it must also be available when
installing from source (the minimum required version is 3.8).
Expand Down Expand Up @@ -68,6 +68,8 @@ path, etc.). The available configuration options are:
quadmath library (off by default),
* ``MPPP_WITH_BOOST_S11N``: enable support for serialisation
via the Boost.serialization library (off by default),
* ``MPPP_WITH_FMT``: enable support for formatting
via the fmt library (off by default),
* ``MPPP_BUILD_TESTS``: build the test suite (off by default),
* ``MPPP_BUILD_BENCHMARKS``: build the benchmarking suite (off by default),
* ``MPPP_BUILD_STATIC_LIBRARY``: build mp++ as a static library, instead
Expand Down Expand Up @@ -98,6 +100,10 @@ path, etc.). The available configuration options are:

The ``MPPP_WITH_BOOST_S11N`` build option.

.. versionadded:: 0.27

The ``MPPP_WITH_FMT`` build option.

Note that the ``MPPP_WITH_QUADMATH`` option, at this time, is available only
using GCC (all the supported versions), Clang
(since version 3.9) and the Intel compiler. When this option is active,
Expand Down Expand Up @@ -279,7 +285,8 @@ variables to signal with which optional dependencies mp++ was compiled:
* ``mp++_WITH_MPC`` if MPC support was enabled,
* ``mp++_WITH_ARB`` if Arb support was enabled,
* ``mp++_WITH_QUADMATH`` if quadmath support was enabled,
* ``mp++_WITH_BOOST_S11N`` if Boost.serialization support was enabled.
* ``mp++_WITH_BOOST_S11N`` if Boost.serialization support was enabled,
* ``mp++_WITH_FMT`` if fmt support was enabled.

.. _inst_plat_specific:

Expand Down
71 changes: 71 additions & 0 deletions doc/real.rst
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,14 @@ The real class
:exception std\:\:invalid_argument: if *p* is outside the range established by
:cpp:func:`mppp::real_prec_min()` and :cpp:func:`mppp::real_prec_max()`.

.. cpp:function:: std::size_t get_nlimbs() const

.. versionadded:: 0.27

Get the number of limbs.

:return: the number of multiprecision limbs (of type :cpp:type:`mp_limb_t`) necessary to represent the significand of ``this``.

.. cpp:function:: template <real_interoperable T> explicit operator T() const

Generic conversion operator.
Expand Down Expand Up @@ -1324,6 +1332,30 @@ Precision handling

:return: the minimum/maximum valid precisions for a :cpp:class:`~mppp::real`.

.. cpp:function:: std::size_t mppp::get_nlimbs(const mppp::real &r)

.. versionadded:: 0.27

Get the number of limbs of a :cpp:class:`~mppp::real`.

:param r: the input argument.

:return: the number of multiprecision limbs (of type :cpp:type:`mp_limb_t`) necessary to represent the significand of *r*.

.. cpp:function:: std::size_t mppp::prec_to_nlimbs(mpfr_prec_t p)

.. versionadded:: 0.27

Convert a precision value into a number of limbs.

:param p: the input precision value.

:return: the number of multiprecision limbs (of type :cpp:type:`mp_limb_t`) necessary to represent
the significand of a :cpp:class:`~mppp::real` with *p* bits of precision.

:exception std\:\:invalid_argument: if *p* is outside the range established by
:cpp:func:`mppp::real_prec_min()` and :cpp:func:`mppp::real_prec_max()`.

.. _real_assignment:

Assignment
Expand Down Expand Up @@ -3110,6 +3142,45 @@ Integer and remainder related functions

:return: a reference to *rop*.

.. cpp:function:: template <mppp::cvr_real T> mppp::real &mppp::nexttoward(mppp::real &rop, T &&x, const mppp::real &y)
.. cpp:function:: template <mppp::cvr_real T> mppp::real &mppp::nextafter(mppp::real &rop, T &&x, const mppp::real &y)

.. versionadded:: 0.27

Returns the next representable value of *x* in the direction of *y* (ternary version).

These functions will set *rop* to the next representable value of *x* in the direction of *y*.
Note that in these functions the precision of *y* is ignored, and the precision of *rop*
will always be set to the precision of *x*. If *x* equals *y*, *rop* will be set to *x*.
If any operand is NaN, *rop* will also be set to NaN.

:param rop: the return value.
:param x: the source value.
:param y: the direction value.

:return: a reference to *rop*.

:exception unspecified: any exception raised by the copy assignment operator of :cpp:class:`~mppp::real`.

.. cpp:function:: template <mppp::cvr_real T> mppp::real mppp::nexttoward(T &&x, const mppp::real &y)
.. cpp:function:: template <mppp::cvr_real T> mppp::real mppp::nextafter(T &&x, const mppp::real &y)

.. versionadded:: 0.27

Returns the next representable value of *x* in the direction of *y* (binary version).

These functions will return the next representable value of *x* in the direction of *y*.
Note that in these functions the precision of *y* is ignored, and the precision of the result
will always be set to the precision of *x*. If *x* equals *y*, *x* will be returned.
If any operand is NaN, the return value will also be NaN.

:param x: the source value.
:param y: the direction value.

:return: the next representable value of *x* in the direction of *y*.

:exception unspecified: any exception raised by the copy assignment operator or the copy constructor of :cpp:class:`~mppp::real`.

.. _real_io:

Input/Output
Expand Down
12 changes: 8 additions & 4 deletions doc/real128.rst
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,8 @@ The real128 class
.. note::

The ``logb()`` function is available when using ``libquadmath``
from GCC 6 onwards.
from GCC 6 onwards. See also the :c:macro:`MPPP_QUADMATH_HAVE_LOGBQ`
definition.

.. versionadded:: 0.21

Expand Down Expand Up @@ -524,7 +525,8 @@ The real128 class
.. note::

The ``exp2()`` function is available when using ``libquadmath``
from GCC 9 onwards.
from GCC 9 onwards. See also the :c:macro:`MPPP_QUADMATH_HAVE_EXP2Q`
definition.

In-place logarithms and exponentials.

Expand Down Expand Up @@ -744,7 +746,8 @@ Conversion
.. note::

The ``logb()`` function is available when using ``libquadmath``
from GCC 6 onwards.
from GCC 6 onwards. See also the :c:macro:`MPPP_QUADMATH_HAVE_LOGBQ`
definition.

.. versionadded:: 0.21

Expand Down Expand Up @@ -1120,7 +1123,8 @@ Logarithms and exponentials
.. note::

The ``exp2()`` function is available when using ``libquadmath``
from GCC 9 onwards.
from GCC 9 onwards. See also the :c:macro:`MPPP_QUADMATH_HAVE_EXP2Q`
definition.

Logarithms and exponentials.

Expand Down
11 changes: 11 additions & 0 deletions doc/tutorial_io.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ format flags in output streams:
std::cout << std::hexfloat << std::uppercase << complex{1.1, 1.3} << '\n'; // "(0X1.199999999999AP+0,0X1.4CCCCCCCCCCCDP+0)"
std::cout << std::fixed << std::showpoint << std::showpos << 42_rq << '\n'; // "+42.000000"

Starting from mp++ 0.27, all of mp++'s multiprecision classes support formatting via the
`{fmt} <https://fmt.dev/latest/index.html>`__ library, provided that mp++ has been built with
the ``MPPP_WITH_FMT`` option enabled (see the :ref:`installation instructions <installation>`):

.. code-block:: c++

#include <iostream>

#include <fmt/core.h>

std::cout << fmt::format("The answer is {}", int_t{42}); // "The answer is 42"

All of mp++'s multiprecision classes also provide ``to_string()`` member functions that convert the multiprecision
values into string representations (see, e.g., :cpp:func:`mppp::integer::to_string()`, :cpp:func:`mppp::rational::to_string()`,
Expand Down
Loading

0 comments on commit 4eab53d

Please sign in to comment.