Skip to content

Commit 4eab53d

Browse files
authored
Merge pull request #296 from bluescarni/pr/real_iter
API additions
2 parents 8bd5a9f + 0e705f9 commit 4eab53d

36 files changed

Lines changed: 946 additions & 230 deletions

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ option(MPPP_WITH_ARB "Enable features relying on Arb." OFF)
3535
option(MPPP_WITH_MPC "Enable features relying on MPC." OFF)
3636
option(MPPP_WITH_QUADMATH "Enable features relying on libquadmath (e.g., the real128 type)." OFF)
3737
option(MPPP_WITH_BOOST_S11N "Enable features relying on the Boost.Serialization library." OFF)
38+
option(MPPP_WITH_FMT "Enable support for the fmt library." OFF)
3839
option(MPPP_TEST_PYBIND11 "Build tests for the pybind11 integration utilities (effective only if MPPP_BUILD_TESTS is TRUE, requires pybind11 and Python).")
3940
mark_as_advanced(MPPP_TEST_PYBIND11)
4041
option(MPPP_BUILD_STATIC_LIBRARY "Build mp++ as a static library, instead of dynamic." OFF)
@@ -411,6 +412,15 @@ if(MPPP_WITH_BOOST_S11N)
411412
target_link_libraries(mp++ PUBLIC Boost::serialization Boost::disable_autolinking)
412413
endif()
413414

415+
# NOTE: need at least version 6.2
416+
# to print 128-bit integers.
417+
set(_MPPP_MIN_FMT_VERSION "6.2")
418+
if(MPPP_WITH_FMT)
419+
find_package(fmt ${_MPPP_MIN_FMT_VERSION} REQUIRED CONFIG)
420+
message(STATUS "fmt version: ${fmt_VERSION}")
421+
target_link_libraries(mp++ PUBLIC fmt::fmt)
422+
endif()
423+
414424
# Mandatory dependency on GMP.
415425
# NOTE: depend on GMP *after* optionally depending on MPFR, as the order
416426
# of the libraries matters on some platforms.
@@ -478,3 +488,4 @@ if(MPPP_BUILD_BENCHMARKS)
478488
endif()
479489

480490
unset(_MPPP_MIN_BOOST_VERSION)
491+
unset(_MPPP_MIN_FMT_VERSION)

appveyor.yml

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ install:
2828
- if [%BUILD_TYPE%]==[MSVC15_64] conda update -n base conda
2929
- if [%BUILD_TYPE%]==[MSVC15_64] conda config --add channels conda-forge
3030
- if [%BUILD_TYPE%]==[MSVC15_64] conda config --set channel_priority strict
31-
- if [%BUILD_TYPE%]==[MSVC15_64] conda create --name mppp cmake mpir mpfr mpc arb pybind11 mpmath python=3.6 boost-cpp
31+
- if [%BUILD_TYPE%]==[MSVC15_64] conda create --name mppp cmake mpir mpfr mpc arb boost-cpp
3232
- if [%BUILD_TYPE%]==[MSVC15_64] call activate mppp
3333

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

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

6666
- 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
6767
- if [%BUILD_TYPE%]==[MSVC15_64] cmake --build . --config Release
68-
- 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
69-
- if [%BUILD_TYPE%]==[MSVC15_64] cmake --build . --config Release --target pybind11_test_01
7068

7169
# This build enables Unicode solutions.
72-
- 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
70+
- 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
7371
- if [%BUILD_TYPE%]==[MSVC17_64] cmake --build . --config Release
74-
- 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
75-
- if [%BUILD_TYPE%]==[MSVC17_64] cmake --build . --config Release --target pybind11_test_01
7672

7773
- 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
7874
- if [%BUILD_TYPE%]==[MSVC15_clang_64] cmake --build . -- -v
@@ -87,15 +83,11 @@ test_script:
8783

8884
- if [%BUILD_TYPE%]==[MSVC15_64] set OLD_PATH=%PATH%
8985
- if [%BUILD_TYPE%]==[MSVC15_64] set PATH=%PATH%;%CD%\Release
90-
- if [%BUILD_TYPE%]==[MSVC15_64] ctest -V -C Release -E pybind11
91-
- if [%BUILD_TYPE%]==[MSVC15_64] set PATH=%OLD_PATH%;%CD%\Release
92-
- if [%BUILD_TYPE%]==[MSVC15_64] ctest -V -C Release -R pybind11
86+
- if [%BUILD_TYPE%]==[MSVC15_64] ctest -V -C Release
9387

9488
- if [%BUILD_TYPE%]==[MSVC17_64] set OLD_PATH=%PATH%
9589
- if [%BUILD_TYPE%]==[MSVC17_64] set PATH=%PATH%;%CD%\Release
96-
- if [%BUILD_TYPE%]==[MSVC17_64] ctest -V -C Release -E pybind11
97-
- if [%BUILD_TYPE%]==[MSVC17_64] set PATH=%OLD_PATH%;%CD%\Release
98-
- if [%BUILD_TYPE%]==[MSVC17_64] ctest -V -C Release -R pybind11
90+
- if [%BUILD_TYPE%]==[MSVC17_64] ctest -V -C Release
9991

10092
# NOTE: no need to alter the PATH, static library build.
10193
- if [%BUILD_TYPE%]==[MSVC15_clang_64] ctest -V

benchmark/CMakeLists.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ if(NOT TARGET Boost::boost)
1414
endif()
1515

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

2119
if(MPPP_BENCHMARK_FLINT)
2220
find_package(mp++_FLINT REQUIRED)

config.hpp.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#cmakedefine MPPP_QUADMATH_HAVE_LOGBQ
3232
@MPPP_STATIC_BUILD@
3333
#cmakedefine MPPP_WITH_BOOST_S11N
34+
#cmakedefine MPPP_WITH_FMT
3435
// clang-format on
3536
// End of defines instantiated by CMake.
3637

doc/changelog.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ Changelog
77
New
88
~~~
99

10+
- Add initial optional support for formatting via the fmt library
11+
(`#296 <https://github.com/bluescarni/mppp/pull/296>`__).
12+
- Add helpers to determine the number of limbs in the significand
13+
of a :cpp:class:`~mppp::real` number
14+
(`#296 <https://github.com/bluescarni/mppp/pull/296>`__).
1015
- Add several ``std`` math overloads for :cpp:class:`~mppp::real`
1116
(`#295 <https://github.com/bluescarni/mppp/pull/295>`__).
1217
- Add hashing capabilities to :cpp:class:`~mppp::real`

doc/definitions.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,36 @@ Macros and definitions
2525
This name is defined if mp++ was configured with support for the quadmath library
2626
(see the :ref:`installation instructions <installation>`).
2727

28+
.. c:macro:: MPPP_QUADMATH_HAVE_EXP2Q
29+
30+
.. versionadded:: 0.27
31+
32+
This name is defined if mp++ was configured with support for a quadmath library version
33+
providing the ``exp2q()`` function
34+
(see the :ref:`installation instructions <installation>`).
35+
36+
.. c:macro:: MPPP_QUADMATH_HAVE_LOGBQ
37+
38+
.. versionadded:: 0.27
39+
40+
This name is defined if mp++ was configured with support for a quadmath library version
41+
providing the ``logbq()`` function
42+
(see the :ref:`installation instructions <installation>`).
43+
2844
.. c:macro:: MPPP_WITH_BOOST_S11N
2945
3046
.. versionadded:: 0.22
3147

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

51+
.. c:macro:: MPPP_WITH_FMT
52+
53+
.. versionadded:: 0.27
54+
55+
This name is defined if mp++ was configured with support for the fmt library
56+
(see the :ref:`installation instructions <installation>`).
57+
3558
.. c:macro:: MPPP_FLOAT128_WITH_LONG_DOUBLE
3659
3760
.. versionadded:: 0.22

doc/installation.rst

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ mp++ has the following dependencies:
3636
be installed separately);
3737
* the `Boost <https://www.boost.org/>`__ libraries, *optional*, currently used
3838
for implementing (de)serialisation and in the benchmarking suite;
39-
* the `{fmt} <https://fmt.dev/latest/index.html>`__ library (at least version 6.2), *optional*, currently used
40-
only in the benchmarking suite.
39+
* the `{fmt} <https://fmt.dev/latest/index.html>`__ library (at least version 6.2), *optional*, used
40+
to provide formatting capabilities to the multiprecision classes and in the benchmarking suite.
4141

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

99101
The ``MPPP_WITH_BOOST_S11N`` build option.
100102

103+
.. versionadded:: 0.27
104+
105+
The ``MPPP_WITH_FMT`` build option.
106+
101107
Note that the ``MPPP_WITH_QUADMATH`` option, at this time, is available only
102108
using GCC (all the supported versions), Clang
103109
(since version 3.9) and the Intel compiler. When this option is active,
@@ -279,7 +285,8 @@ variables to signal with which optional dependencies mp++ was compiled:
279285
* ``mp++_WITH_MPC`` if MPC support was enabled,
280286
* ``mp++_WITH_ARB`` if Arb support was enabled,
281287
* ``mp++_WITH_QUADMATH`` if quadmath support was enabled,
282-
* ``mp++_WITH_BOOST_S11N`` if Boost.serialization support was enabled.
288+
* ``mp++_WITH_BOOST_S11N`` if Boost.serialization support was enabled,
289+
* ``mp++_WITH_FMT`` if fmt support was enabled.
283290

284291
.. _inst_plat_specific:
285292

doc/real.rst

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,14 @@ The real class
676676
:exception std\:\:invalid_argument: if *p* is outside the range established by
677677
:cpp:func:`mppp::real_prec_min()` and :cpp:func:`mppp::real_prec_max()`.
678678

679+
.. cpp:function:: std::size_t get_nlimbs() const
680+
681+
.. versionadded:: 0.27
682+
683+
Get the number of limbs.
684+
685+
:return: the number of multiprecision limbs (of type :cpp:type:`mp_limb_t`) necessary to represent the significand of ``this``.
686+
679687
.. cpp:function:: template <real_interoperable T> explicit operator T() const
680688

681689
Generic conversion operator.
@@ -1324,6 +1332,30 @@ Precision handling
13241332

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

1335+
.. cpp:function:: std::size_t mppp::get_nlimbs(const mppp::real &r)
1336+
1337+
.. versionadded:: 0.27
1338+
1339+
Get the number of limbs of a :cpp:class:`~mppp::real`.
1340+
1341+
:param r: the input argument.
1342+
1343+
:return: the number of multiprecision limbs (of type :cpp:type:`mp_limb_t`) necessary to represent the significand of *r*.
1344+
1345+
.. cpp:function:: std::size_t mppp::prec_to_nlimbs(mpfr_prec_t p)
1346+
1347+
.. versionadded:: 0.27
1348+
1349+
Convert a precision value into a number of limbs.
1350+
1351+
:param p: the input precision value.
1352+
1353+
:return: the number of multiprecision limbs (of type :cpp:type:`mp_limb_t`) necessary to represent
1354+
the significand of a :cpp:class:`~mppp::real` with *p* bits of precision.
1355+
1356+
:exception std\:\:invalid_argument: if *p* is outside the range established by
1357+
:cpp:func:`mppp::real_prec_min()` and :cpp:func:`mppp::real_prec_max()`.
1358+
13271359
.. _real_assignment:
13281360

13291361
Assignment
@@ -3110,6 +3142,45 @@ Integer and remainder related functions
31103142

31113143
:return: a reference to *rop*.
31123144

3145+
.. cpp:function:: template <mppp::cvr_real T> mppp::real &mppp::nexttoward(mppp::real &rop, T &&x, const mppp::real &y)
3146+
.. cpp:function:: template <mppp::cvr_real T> mppp::real &mppp::nextafter(mppp::real &rop, T &&x, const mppp::real &y)
3147+
3148+
.. versionadded:: 0.27
3149+
3150+
Returns the next representable value of *x* in the direction of *y* (ternary version).
3151+
3152+
These functions will set *rop* to the next representable value of *x* in the direction of *y*.
3153+
Note that in these functions the precision of *y* is ignored, and the precision of *rop*
3154+
will always be set to the precision of *x*. If *x* equals *y*, *rop* will be set to *x*.
3155+
If any operand is NaN, *rop* will also be set to NaN.
3156+
3157+
:param rop: the return value.
3158+
:param x: the source value.
3159+
:param y: the direction value.
3160+
3161+
:return: a reference to *rop*.
3162+
3163+
:exception unspecified: any exception raised by the copy assignment operator of :cpp:class:`~mppp::real`.
3164+
3165+
.. cpp:function:: template <mppp::cvr_real T> mppp::real mppp::nexttoward(T &&x, const mppp::real &y)
3166+
.. cpp:function:: template <mppp::cvr_real T> mppp::real mppp::nextafter(T &&x, const mppp::real &y)
3167+
3168+
.. versionadded:: 0.27
3169+
3170+
Returns the next representable value of *x* in the direction of *y* (binary version).
3171+
3172+
These functions will return the next representable value of *x* in the direction of *y*.
3173+
Note that in these functions the precision of *y* is ignored, and the precision of the result
3174+
will always be set to the precision of *x*. If *x* equals *y*, *x* will be returned.
3175+
If any operand is NaN, the return value will also be NaN.
3176+
3177+
:param x: the source value.
3178+
:param y: the direction value.
3179+
3180+
:return: the next representable value of *x* in the direction of *y*.
3181+
3182+
:exception unspecified: any exception raised by the copy assignment operator or the copy constructor of :cpp:class:`~mppp::real`.
3183+
31133184
.. _real_io:
31143185

31153186
Input/Output

doc/real128.rst

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,8 @@ The real128 class
355355
.. note::
356356

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

360361
.. versionadded:: 0.21
361362

@@ -524,7 +525,8 @@ The real128 class
524525
.. note::
525526

526527
The ``exp2()`` function is available when using ``libquadmath``
527-
from GCC 9 onwards.
528+
from GCC 9 onwards. See also the :c:macro:`MPPP_QUADMATH_HAVE_EXP2Q`
529+
definition.
528530

529531
In-place logarithms and exponentials.
530532

@@ -744,7 +746,8 @@ Conversion
744746
.. note::
745747

746748
The ``logb()`` function is available when using ``libquadmath``
747-
from GCC 6 onwards.
749+
from GCC 6 onwards. See also the :c:macro:`MPPP_QUADMATH_HAVE_LOGBQ`
750+
definition.
748751

749752
.. versionadded:: 0.21
750753

@@ -1120,7 +1123,8 @@ Logarithms and exponentials
11201123
.. note::
11211124

11221125
The ``exp2()`` function is available when using ``libquadmath``
1123-
from GCC 9 onwards.
1126+
from GCC 9 onwards. See also the :c:macro:`MPPP_QUADMATH_HAVE_EXP2Q`
1127+
definition.
11241128

11251129
Logarithms and exponentials.
11261130

doc/tutorial_io.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@ format flags in output streams:
3737
std::cout << std::hexfloat << std::uppercase << complex{1.1, 1.3} << '\n'; // "(0X1.199999999999AP+0,0X1.4CCCCCCCCCCCDP+0)"
3838
std::cout << std::fixed << std::showpoint << std::showpos << 42_rq << '\n'; // "+42.000000"
3939

40+
Starting from mp++ 0.27, all of mp++'s multiprecision classes support formatting via the
41+
`{fmt} <https://fmt.dev/latest/index.html>`__ library, provided that mp++ has been built with
42+
the ``MPPP_WITH_FMT`` option enabled (see the :ref:`installation instructions <installation>`):
43+
44+
.. code-block:: c++
45+
46+
#include <iostream>
47+
48+
#include <fmt/core.h>
49+
50+
std::cout << fmt::format("The answer is {}", int_t{42}); // "The answer is 42"
4051

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

0 commit comments

Comments
 (0)