<commit_before>Multiprecision floats
=====================

.. note::

   The functionality described in this section is available only if mp++ was configured
   with the ``MPPP_WITH_MPFR`` option enabled (see the :ref:`installation instructions <installation>`).

.. versionadded:: 0.5

*#include <mp++/real.hpp>*

The ``real`` class
------------------

.. doxygenclass:: mppp::real
   :members:

Types
-----

.. cpp:type:: mppp::mpfr_struct_t = std::remove_extent<mpfr_t>::type

   The C structure used by MPFR to represent arbitrary-precision floats.
   The MPFR type ``mpfr_t`` is defined as an array of size 1 of this structure.

.. cpp:type:: mpfr_prec_t

   An integral type defined by the MPFR library, used to represent the precision of ``mpfr_t``
   and (by extension) :cpp:class:`~mppp::real` objects.

.. cpp:type:: mpfr_exp_t

   An integral type defined by the MPFR library, used to represent the exponent of ``mpfr_t``
   and (by extension) :cpp:class:`~mppp::real` objects.

.. cpp:enum-class:: mppp::real_kind

   This scoped enum is used to initialise a :cpp:class:`~mppp::real` with
   one of the three special values NaN, infinity or zero.

   .. cpp:enumerator:: nan = MPFR_NAN_KIND
   .. cpp:enumerator:: inf = MPFR_INF_KIND
   .. cpp:enumerator:: zero = MPFR_ZERO_KIND

.. seealso::

   https://www.mpfr.org/mpfr-current/mpfr.html#Nomenclature-and-Types

Concepts
--------

.. cpp:concept:: template <typename T> mppp::RealInteroperable

   This concept is satisfied if the type ``T`` can interoperate with :cpp:class:`~mppp::real`.
   Specifically, this concept will be ``true`` if ``T`` is either:

   * a :cpp:concept:`CppInteroperable` type, or
   * an :cpp:class:`~mppp::integer`, or
   * a :cpp:class:`~mppp::rational`, or
   * :cpp:class:`~mppp::real128`.

.. cpp:concept:: template <typename T> mppp::CvrReal

   This concept is satisfied if the type ``T``, after the removal of reference and cv qualifiers,
   is the same as :cpp:class:`mppp::real`.

.. cpp:concept:: template <typename... Args> mppp::RealSetArgs

   This concept is satisfied if the types in the parameter pack ``Args``
   can be used as argument types in one of the :cpp:func:`mppp::real::set()` method overloads.
   In other words, this concept is satisfied if the expression

   .. code-block:: c++

      r.set(x, y, z, ...);

   is valid (where ``r`` is a non-const :cpp:class:`~mppp::real` and ``x``, ``y``, ``z``, etc. are const
   references to the types in ``Args``).

.. cpp:concept:: template <typename T, typename U> mppp::RealOpTypes

   This concept is satisfied if the types ``T`` and ``U`` are suitable for use in the
   generic binary :ref:`operators <real_operators>` and :ref:`functions <real_functions>`
   involving :cpp:class:`~mppp::real`. Specifically, the concept will be ``true`` if either:

   * ``T`` and ``U`` both satisfy :cpp:concept:`~mppp::CvrReal`,
   * one type satisfies :cpp:concept:`~mppp::CvrReal` and the other type, after the removal of reference
     and cv qualifiers, satisfies :cpp:concept:`~mppp::RealInteroperable`.

   A corresponding boolean type trait called ``are_real_op_types`` is also available (even if the compiler does
   not support concepts).

.. cpp:concept:: template <typename T, typename U> mppp::RealInPlaceOpTypes

   This concept is satisfied if the types ``T`` and ``U`` are suitable for use in the
   generic in-place :ref:`operators <real_operators>`
   involving :cpp:class:`~mppp::real`. Specifically, the concept will be ``true`` if
   ``T`` and ``U`` satisfy :cpp:concept:`~mppp::RealOpTypes` and ``T``, after the removal
   of reference, is not const.

.. _real_functions:

Functions
---------

.. _real_prec:

Precision handling
~~~~~~~~~~~~~~~~~~

.. doxygengroup:: real_prec
   :content-only:

.. _real_assignment:

Assignment
~~~~~~~~~~

.. doxygengroup:: real_assignment
   :content-only:

.. _real_conversion:

Conversion
~~~~~~~~~~

.. doxygengroup:: real_conversion
   :content-only:

.. _real_arithmetic:

Arithmetic
~~~~~~~~~~

.. doxygengroup:: real_arithmetic
   :content-only:

.. _real_comparison:

Comparison
~~~~~~~~~~

.. doxygengroup:: real_comparison
   :content-only:

.. _real_roots:

Roots
~~~~~

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sqrt(mppp::real &rop, T &&op)

   Binary :cpp:class:`~mppp::real` square root.

   This function will compute the square root of *op* and store it
   into *rop*. The precision of the result will be equal to the precision
   of *op*.

   If *op* is -0, *rop* will be set to -0. If *op* is negative, *rop* will be set to NaN.

   :param rop: the return value.
   :param op: the operand.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sqrt(T &&r)

   Unary :cpp:class:`~mppp::real` square root.

   This function will compute and return the square root of *r*.
   The precision of the result will be equal to the precision of *r*.

   If *r* is -0, the result will be -0. If *r* is negative, the result will be NaN.

   :param r: the operand.

   :return: the square root of *r*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sqrt1pm1(mppp::real &rop, T &&op)

   .. versionadded:: 0.19

   .. note::
      This function is available only if mp++ was
      configured with the ``MPPP_WITH_ARB`` option enabled
      (see the :ref:`installation instructions <installation>`).

   Binary :cpp:class:`~mppp::real` sqrt1pm1.

   This function will compute :math:`\sqrt{1+x}-1`, where :math:`x` is the value of *op*,
   and store the result into *rop*. The precision of the result will be equal to the precision
   of *op*.

   :param rop: the return value.
   :param op: the operand.

   :return: a reference to *rop*.

   :exception std\:\:invalid_argument: if the conversion between Arb and MPFR types
     fails because of (unlikely) overflow conditions.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sqrt1pm1(T &&r)

   .. versionadded:: 0.19

   .. note::
      This function is available only if mp++ was
      configured with the ``MPPP_WITH_ARB`` option enabled
      (see the :ref:`installation instructions <installation>`).

   Unary :cpp:class:`~mppp::real` sqrt1pm1.

   This function will compute and return :math:`\sqrt{1+x}-1`, where :math:`x`
   is the value of *r*.
   The precision of the result will be equal to the precision of *r*.

   :param r: the operand.

   :return: the sqrt1pm1 of *r*.

   :exception std\:\:invalid_argument: if the conversion between Arb and MPFR types
     fails because of (unlikely) overflow conditions.

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::rec_sqrt(mppp::real &rop, T &&op)

   .. versionadded:: 0.12

   Binary :cpp:class:`~mppp::real` reciprocal square root.

   This function will compute the reciprocal square root of *op* and store it into *rop*. The precision
   of the result will be equal to the precision of *op*.

   If *op* is zero, *rop* will be set to a positive infinity (regardless of the sign of *op*).
   If *op* is a positive infinity, *rop* will be set to +0. If *op* is negative, *rop* will be set to NaN.

   :param rop: the return value.
   :param op: the operand.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::rec_sqrt(T &&r)

   .. versionadded:: 0.12

   Unary :cpp:class:`~mppp::real` reciprocal square root.

   This function will compute and return the reciprocal square root of *r*.
   The precision of the result will be equal to the precision of *r*.

   If *r* is zero, a positive infinity will be returned (regardless of the sign of *r*).
   If *r* is a positive infinity, +0 will be returned. If *r* is negative,
   NaN will be returned.

   :param r: the operand.

   :return: the reciprocal square root of *r*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::cbrt(mppp::real &rop, T &&op)

   .. versionadded:: 0.12

   Binary :cpp:class:`~mppp::real` cubic root.

   This function will compute the cubic root of *op* and store it
   into *rop*. The precision of the result will be equal to the precision
   of *op*.

   :param rop: the return value.
   :param op: the operand.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::cbrt(T &&r)

   .. versionadded:: 0.12

   Unary :cpp:class:`~mppp::real` cubic root.

   This function will compute and return the cubic root of *r*.
   The precision of the result will be equal to the precision of *r*.

   :param r: the operand.

   :return: the cubic root of *r*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::rootn_ui(mppp::real &rop, T &&op, unsigned long k)

   .. versionadded:: 0.12

   .. note::
      This function is available from MPFR 4 onwards.

   Binary :cpp:class:`~mppp::real` k-th root.

   This function will compute the k-th root of *op* and store it
   into *rop*. The precision of the result will be equal to the precision
   of *op*.

   If *k* is zero, the result will be NaN. If *k* is odd (resp. even) and *op*
   negative (including negative infinity), the result will be a negative number (resp. NaN).
   If *op* is zero, the result will be zero with the sign obtained by the usual limit rules, i.e.,
   the same sign as *op* if *k* is odd, and positive if *k* is even.

   :param rop: the return value.
   :param op: the operand.
   :param k: the degree of the root.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::rootn_ui(T &&r, unsigned long k)

   .. versionadded:: 0.12

   .. note::
      This function is available from MPFR 4 onwards.

   Unary :cpp:class:`~mppp::real` k-th root.

   This function will compute and return the k-th root of *r*.
   The precision of the result will be equal to the precision
   of *r*.

   If *k* is zero, the result will be NaN. If *k* is odd (resp. even) and *r*
   negative (including negative infinity), the result will be a negative number (resp. NaN).
   If *r* is zero, the result will be zero with the sign obtained by the usual limit rules, i.e.,
   the same sign as *r* if *k* is odd, and positive if *k* is even.

   :param r: the operand.
   :param k: the degree of the root.

   :return: the k-th root of *r*.

.. _real_exponentiation:

Exponentiation
~~~~~~~~~~~~~~

.. cpp:function:: template <mppp::CvrReal T, mppp::CvrReal U> mppp::real &mppp::pow(mppp::real &rop, T &&op1, U &&op2)

   Ternary exponentiation.

   This function will set *rop* to *op1* raised to the power of *op2*.
   The precision of *rop* will be set to the largest precision among the operands.

   :param rop: the return value.
   :param op1: the base.
   :param op2: the exponent.

   :return: a reference to *rop*.

.. cpp:function:: template <typename T, typename U> mppp::real pow(T &&op1, U &&op2)

   .. note::

      This function participates in overload resolution only if ``T`` and ``U`` satisfy
      the :cpp:concept:`~mppp::RealOpTypes` concept.

   Binary exponentiation.

   This function will compute and return *op1* raised to the power of *op2*.
   The precision of the result will be set to the largest precision among the operands.

   Non-:cpp:class:`~mppp::real` operands will be converted to :cpp:class:`~mppp::real`
   before performing the operation. The conversion of non-:cpp:class:`~mppp::real` operands
   to :cpp:class:`~mppp::real` follows the same heuristics described in the generic assignment operator of
   :cpp:class:`~mppp::real`. Specifically, the precision of the conversion is either the default
   precision, if set, or it is automatically deduced depending on the type and value of the
   operand to be converted.

   :param op1: the base.
   :param op2: the exponent.

   :return: *op1* raised to the power of *op2*.

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

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sqr(mppp::real &rop, T &&op)

   .. versionadded:: 0.19

   Binary :cpp:class:`~mppp::real` squaring.

   This function will compute the square of *op* and store it
   into *rop*. The precision of the result will be equal to the precision
   of *op*.

   :param rop: the return value.
   :param op: the operand.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sqr(T &&r)

   .. versionadded:: 0.19

   Unary :cpp:class:`~mppp::real` squaring.

   This function will compute and return the square of *r*.
   The precision of the result will be equal to the precision of *r*.

   :param r: the operand.

   :return: the square of *r*.

.. _real_trig:

Trigonometry
~~~~~~~~~~~~

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sin(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::cos(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::tan(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sec(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::csc(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::cot(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sin_pi(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::cos_pi(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::tan_pi(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::cot_pi(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sinc(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sinc_pi(mppp::real &rop, T &&x)

   .. note::
      The functions ``sin_pi()``, ``cos_pi()``, ``tan_pi()``,
      ``cot_pi()``, ``sinc()`` and ``sinc_pi()`` are available only
      if mp++ was
      configured with the ``MPPP_WITH_ARB`` option enabled
      (see the :ref:`installation instructions <installation>`).

   Binary basic trigonometric functions.

   These functions will set *rop* to, respectively:

   * :math:`\sin\left( x \right)`,
   * :math:`\cos\left( x \right)`,
   * :math:`\tan\left( x \right)`,
   * :math:`\sec\left( x \right)`,
   * :math:`\csc\left( x \right)`,
   * :math:`\cot\left( x \right)`,
   * :math:`\sin\left( \pi x \right)`,
   * :math:`\cos\left( \pi x \right)`,
   * :math:`\tan\left( \pi x \right)`,
   * :math:`\cot\left( \pi x \right)`,
   * :math:`\frac{\sin\left( x \right)}{x}`,
   * :math:`\frac{\sin\left( \pi x \right)}{\pi x}`.

   The precision of the result will be equal to the precision of *x*.

   :param rop: the return value.
   :param x: the argument.

   :return: a reference to *rop*.

   :exception std\:\:invalid_argument: if the conversion between Arb and MPFR types
     fails because of (unlikely) overflow conditions.

   .. versionadded:: 0.19

      The functions ``sin_pi()``, ``cos_pi()``, ``tan_pi()``,
      ``cot_pi()``, ``sinc()`` and ``sinc_pi()``.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sin(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::cos(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::tan(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sec(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::csc(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::cot(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sin_pi(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::cos_pi(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::tan_pi(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::cot_pi(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sinc(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sinc_pi(T &&x)

   .. note::
      The functions ``sin_pi()``, ``cos_pi()``, ``tan_pi()``,
      ``cot_pi()``, ``sinc()`` and ``sinc_pi()`` are available only
      if mp++ was
      configured with the ``MPPP_WITH_ARB`` option enabled
      (see the :ref:`installation instructions <installation>`).

   Unary basic trigonometric functions.

   These functions will return, respectively:

   * :math:`\sin\left( x \right)`,
   * :math:`\cos\left( x \right)`,
   * :math:`\tan\left( x \right)`,
   * :math:`\sec\left( x \right)`,
   * :math:`\csc\left( x \right)`,
   * :math:`\cot\left( x \right)`,
   * :math:`\sin\left( \pi x \right)`,
   * :math:`\cos\left( \pi x \right)`,
   * :math:`\tan\left( \pi x \right)`,
   * :math:`\cot\left( \pi x \right)`,
   * :math:`\frac{\sin\left( x \right)}{x}`,
   * :math:`\frac{\sin\left( \pi x \right)}{\pi x}`.

   The precision of the result will be equal to the precision of *x*.

   :param x: the argument.

   :return: the trigonometric function of *x*.

   :exception std\:\:invalid_argument: if the conversion between Arb and MPFR types
     fails because of (unlikely) overflow conditions.

   .. versionadded:: 0.19

      The functions ``sin_pi()``, ``cos_pi()``, ``tan_pi()``,
      ``cot_pi()``, ``sinc()`` and ``sinc_pi()``.

.. cpp:function:: template <mppp::CvrReal T> void mppp::sin_cos(mppp::real &sop, mppp::real &cop, T &&op)

   Simultaneous sine and cosine.

   This function will set *sop* and *cop* respectively to the sine and cosine of *op*.
   *sop* and *cop* must be distinct objects. The precision of *sop* and *rop* will be set to the
   precision of *op*.

   :param sop: the sine return value.
   :param cop: the cosine return value.
   :param op: the operand.

   :exception std\:\:invalid_argument: if *sop* and *cop* are the same object.

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::asin(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::acos(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::atan(mppp::real &rop, T &&op)

   Binary basic inverse trigonometric functions.

   These functions will set *rop* to, respectively, the arcsine, arccosine and
   arctangent of *op*.
   The precision of the result will be equal to the precision of *op*.

   :param rop: the return value.
   :param op: the argument.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::asin(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::acos(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::atan(T &&r)

   Unary basic inverse trigonometric functions.

   These functions will return, respectively, the arcsine, arccosine and
   arctangent of *r*.
   The precision of the result will be equal to the precision of *r*.

   :param r: the argument.

   :return: the arcsine, arccosine or arctangent of *r*.

.. cpp:function:: template <mppp::CvrReal T, mppp::CvrReal U> mppp::real &mppp::atan2(mppp::real &rop, T &&y, U &&x)

   Ternary arctangent-2.

   This function will set *rop* to the arctangent-2 of *y* and *x*.
   The precision of *rop* will be set to the largest precision among the operands.

   :param rop: the return value.
   :param y: the sine argument.
   :param x: the cosine argument.

   :return: a reference to *rop*.

.. cpp:function:: template <typename T, mppp::RealOpTypes<T> U> mppp::real mppp::atan2(T &&y, U &&x)

   Binary arctangent-2.

   This function will compute and return the arctangent-2 of *y* and *x*.

   Non-:cpp:class:`~mppp::real` operands will be converted to :cpp:class:`~mppp::real`
   before performing the operation. The conversion of non-:cpp:class:`~mppp::real` operands
   to :cpp:class:`~mppp::real` follows the same heuristics described in the generic assignment
   operator of :cpp:class:`~mppp::real`. Specifically, the precision of the conversion is
   either the default precision, if set, or it is automatically deduced depending on the type
   and value of the operand to be converted.

   :param y: the sine argument.
   :param x: the cosine argument.

   :return: the arctangent-2 of *y* and *x*.

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

.. _real_hyper:

Hyperbolic functions
~~~~~~~~~~~~~~~~~~~~

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sinh(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::cosh(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::tanh(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sech(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::csch(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::coth(mppp::real &rop, T &&op)

   Binary basic hyperbolic functions.

   These functions will set *rop* to, respectively, the hyperbolic sine, cosine, tangent, secant,
   cosecant and cotangent of *op*.
   The precision of the result will be equal to the precision of *op*.

   :param rop: the return value.
   :param op: the argument.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sinh(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::cosh(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::tanh(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sech(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::csch(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::coth(T &&r)

   Unary basic hyperbolic functions.

   These functions will return, respectively, the hyperbolic sine, cosine, tangent,
   secant, cosecant and cotangent of *r*.
   The precision of the result will be equal to the precision of *r*.

   :param r: the argument.

   :return: the hyperbolic sine, cosine, tangent, secant, cosecant or cotangent of *r*.

.. cpp:function:: template <mppp::CvrReal T> void mppp::sinh_cosh(mppp::real &sop, mppp::real &cop, T &&op)

   Simultaneous hyperbolic sine and cosine.

   This function will set *sop* and *cop* respectively to the hyperbolic sine and cosine of *op*.
   *sop* and *cop* must be distinct objects. The precision of *sop* and *rop* will be set to the
   precision of *op*.

   :param sop: the hyperbolic sine return value.
   :param cop: the hyperbolic cosine return value.
   :param op: the operand.

   :exception std\:\:invalid_argument: if *sop* and *cop* are the same object.

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::asinh(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::acosh(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::atanh(mppp::real &rop, T &&op)

   Binary basic inverse hyperbolic functions.

   These functions will set *rop* to, respectively, the inverse hyperbolic sine, cosine and
   tangent of *op*.
   The precision of the result will be equal to the precision of *op*.

   :param rop: the return value.
   :param op: the argument.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::asinh(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::acosh(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::atanh(T &&r)

   Unary basic inverse hyperbolic functions.

   These functions will return, respectively, the inverse hyperbolic sine, cosine and
   tangent of *r*.
   The precision of the result will be equal to the precision of *r*.

   :param r: the argument.

   :return: the inverse hyperbolic sine, cosine or tangent of *r*.

.. _real_logexp:

Logarithms and exponentials
~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::exp(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::exp2(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::exp10(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::expm1(mppp::real &rop, T &&op)

   Binary exponentials.

   These functions will set *rop* to, respectively,

   * ``e**op``,
   * ``2**op``,
   * ``10**op``,
   * ``e**op-1``.

   The precision of the result will be equal to the precision of *op*.

   :param rop: the return value.
   :param op: the exponent.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::exp(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::exp2(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::exp10(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::expm1(T &&r)

   Unary exponentials.

   These functions will return, respectively,

   * ``e**r``,
   * ``2**r``,
   * ``10**r``,
   * ``e**r-1``.

   The precision of the result will be equal to the precision of *r*.

   :param r: the exponent.

   :return: the exponential of *r*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::log(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::log2(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::log10(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::log1p(mppp::real &rop, T &&op)

   Binary logarithms.

   These functions will set *rop* to, respectively,

   * ``log(op)``,
   * ``log2(op)``,
   * ``log10(op)``,
   * ``log(1+op)``.

   The precision of the result will be equal to the precision of *op*.

   :param rop: the return value.
   :param op: the operand.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::log(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::log2(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::log10(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::log1p(T &&r)

   Unary logarithms.

   These functions will return, respectively,

   * ``log(r)``,
   * ``log2(r)``,
   * ``log10(r)``,
   * ``log(1+op)``.

   The precision of the result will be equal to the precision of *r*.

   :param r: the operand.

   :return: the logarithm of *r*.

.. cpp:function:: template <mppp::CvrReal T, mppp::CvrReal U> mppp::real &mppp::log_hypot(mppp::real &rop, T &&x, U &&y)

   .. versionadded:: 0.19

   .. note::
      This function is available only if mp++ was
      configured with the ``MPPP_WITH_ARB`` option enabled
      (see the :ref:`installation instructions <installation>`).

   Ternary log hypot function.

   This function will set *rop* to :math:`\log\left(\sqrt{x^2+y^2}\right)`.
   The precision of *rop* will be set to the largest precision among the operands.

   :param rop: the return value.
   :param x: the first argument.
   :param y: the second argument.

   :return: a reference to *rop*.

   :exception std\:\:invalid_argument: if the conversion between Arb and MPFR types
     fails because of (unlikely) overflow conditions.

.. cpp:function:: template <typename T, typename U> mppp::real mppp::log_hypot(T &&x, U &&y)

   .. versionadded:: 0.19
<commit_msg>More small doc fixes.<commit_after>Multiprecision floats
=====================

.. note::

   The functionality described in this section is available only if mp++ was configured
   with the ``MPPP_WITH_MPFR`` option enabled (see the :ref:`installation instructions <installation>`).

.. versionadded:: 0.5

*#include <mp++/real.hpp>*

The ``real`` class
------------------

.. doxygenclass:: mppp::real
   :members:

Types
-----

.. cpp:type:: mppp::mpfr_struct_t = std::remove_extent<mpfr_t>::type

   The C structure used by MPFR to represent arbitrary-precision floats.
   The MPFR type ``mpfr_t`` is defined as an array of size 1 of this structure.

.. cpp:type:: mpfr_prec_t

   An integral type defined by the MPFR library, used to represent the precision of ``mpfr_t``
   and (by extension) :cpp:class:`~mppp::real` objects.

.. cpp:type:: mpfr_exp_t

   An integral type defined by the MPFR library, used to represent the exponent of ``mpfr_t``
   and (by extension) :cpp:class:`~mppp::real` objects.

.. cpp:enum-class:: mppp::real_kind

   This scoped enum is used to initialise a :cpp:class:`~mppp::real` with
   one of the three special values NaN, infinity or zero.

   .. cpp:enumerator:: nan = MPFR_NAN_KIND
   .. cpp:enumerator:: inf = MPFR_INF_KIND
   .. cpp:enumerator:: zero = MPFR_ZERO_KIND

.. seealso::

   https://www.mpfr.org/mpfr-current/mpfr.html#Nomenclature-and-Types

Concepts
--------

.. cpp:concept:: template <typename T> mppp::RealInteroperable

   This concept is satisfied if the type ``T`` can interoperate with :cpp:class:`~mppp::real`.
   Specifically, this concept will be ``true`` if ``T`` is either:

   * a :cpp:concept:`CppInteroperable` type, or
   * an :cpp:class:`~mppp::integer`, or
   * a :cpp:class:`~mppp::rational`, or
   * :cpp:class:`~mppp::real128`.

.. cpp:concept:: template <typename T> mppp::CvrReal

   This concept is satisfied if the type ``T``, after the removal of reference and cv qualifiers,
   is the same as :cpp:class:`mppp::real`.

.. cpp:concept:: template <typename... Args> mppp::RealSetArgs

   This concept is satisfied if the types in the parameter pack ``Args``
   can be used as argument types in one of the :cpp:func:`mppp::real::set()` method overloads.
   In other words, this concept is satisfied if the expression

   .. code-block:: c++

      r.set(x, y, z, ...);

   is valid (where ``r`` is a non-const :cpp:class:`~mppp::real` and ``x``, ``y``, ``z``, etc. are const
   references to the types in ``Args``).

.. cpp:concept:: template <typename T, typename U> mppp::RealOpTypes

   This concept is satisfied if the types ``T`` and ``U`` are suitable for use in the
   generic binary :ref:`operators <real_operators>` and :ref:`functions <real_functions>`
   involving :cpp:class:`~mppp::real`. Specifically, the concept will be ``true`` if either:

   * ``T`` and ``U`` both satisfy :cpp:concept:`~mppp::CvrReal`,
   * one type satisfies :cpp:concept:`~mppp::CvrReal` and the other type, after the removal of reference
     and cv qualifiers, satisfies :cpp:concept:`~mppp::RealInteroperable`.

   A corresponding boolean type trait called ``are_real_op_types`` is also available (even if the compiler does
   not support concepts).

.. cpp:concept:: template <typename T, typename U> mppp::RealInPlaceOpTypes

   This concept is satisfied if the types ``T`` and ``U`` are suitable for use in the
   generic in-place :ref:`operators <real_operators>`
   involving :cpp:class:`~mppp::real`. Specifically, the concept will be ``true`` if
   ``T`` and ``U`` satisfy :cpp:concept:`~mppp::RealOpTypes` and ``T``, after the removal
   of reference, is not const.

.. _real_functions:

Functions
---------

.. _real_prec:

Precision handling
~~~~~~~~~~~~~~~~~~

.. doxygengroup:: real_prec
   :content-only:

.. _real_assignment:

Assignment
~~~~~~~~~~

.. doxygengroup:: real_assignment
   :content-only:

.. _real_conversion:

Conversion
~~~~~~~~~~

.. doxygengroup:: real_conversion
   :content-only:

.. _real_arithmetic:

Arithmetic
~~~~~~~~~~

.. doxygengroup:: real_arithmetic
   :content-only:

.. _real_comparison:

Comparison
~~~~~~~~~~

.. doxygengroup:: real_comparison
   :content-only:

.. _real_roots:

Roots
~~~~~

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sqrt(mppp::real &rop, T &&op)

   Binary :cpp:class:`~mppp::real` square root.

   This function will compute the square root of *op* and store it
   into *rop*. The precision of the result will be equal to the precision
   of *op*.

   If *op* is -0, *rop* will be set to -0. If *op* is negative, *rop* will be set to NaN.

   :param rop: the return value.
   :param op: the operand.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sqrt(T &&r)

   Unary :cpp:class:`~mppp::real` square root.

   This function will compute and return the square root of *r*.
   The precision of the result will be equal to the precision of *r*.

   If *r* is -0, the result will be -0. If *r* is negative, the result will be NaN.

   :param r: the operand.

   :return: the square root of *r*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sqrt1pm1(mppp::real &rop, T &&op)

   .. versionadded:: 0.19

   .. note::
      This function is available only if mp++ was
      configured with the ``MPPP_WITH_ARB`` option enabled
      (see the :ref:`installation instructions <installation>`).

   Binary :cpp:class:`~mppp::real` sqrt1pm1.

   This function will compute :math:`\sqrt{1+x}-1`, where :math:`x` is the value of *op*,
   and store the result into *rop*. The precision of the result will be equal to the precision
   of *op*.

   :param rop: the return value.
   :param op: the operand.

   :return: a reference to *rop*.

   :exception std\:\:invalid_argument: if the conversion between Arb and MPFR types
     fails because of (unlikely) overflow conditions.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sqrt1pm1(T &&r)

   .. versionadded:: 0.19

   .. note::
      This function is available only if mp++ was
      configured with the ``MPPP_WITH_ARB`` option enabled
      (see the :ref:`installation instructions <installation>`).

   Unary :cpp:class:`~mppp::real` sqrt1pm1.

   This function will compute and return :math:`\sqrt{1+x}-1`, where :math:`x`
   is the value of *r*.
   The precision of the result will be equal to the precision of *r*.

   :param r: the operand.

   :return: the sqrt1pm1 of *r*.

   :exception std\:\:invalid_argument: if the conversion between Arb and MPFR types
     fails because of (unlikely) overflow conditions.

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::rec_sqrt(mppp::real &rop, T &&op)

   .. versionadded:: 0.12

   Binary :cpp:class:`~mppp::real` reciprocal square root.

   This function will compute the reciprocal square root of *op* and store it into *rop*. The precision
   of the result will be equal to the precision of *op*.

   If *op* is zero, *rop* will be set to a positive infinity (regardless of the sign of *op*).
   If *op* is a positive infinity, *rop* will be set to +0. If *op* is negative, *rop* will be set to NaN.

   :param rop: the return value.
   :param op: the operand.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::rec_sqrt(T &&r)

   .. versionadded:: 0.12

   Unary :cpp:class:`~mppp::real` reciprocal square root.

   This function will compute and return the reciprocal square root of *r*.
   The precision of the result will be equal to the precision of *r*.

   If *r* is zero, a positive infinity will be returned (regardless of the sign of *r*).
   If *r* is a positive infinity, +0 will be returned. If *r* is negative,
   NaN will be returned.

   :param r: the operand.

   :return: the reciprocal square root of *r*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::cbrt(mppp::real &rop, T &&op)

   .. versionadded:: 0.12

   Binary :cpp:class:`~mppp::real` cubic root.

   This function will compute the cubic root of *op* and store it
   into *rop*. The precision of the result will be equal to the precision
   of *op*.

   :param rop: the return value.
   :param op: the operand.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::cbrt(T &&r)

   .. versionadded:: 0.12

   Unary :cpp:class:`~mppp::real` cubic root.

   This function will compute and return the cubic root of *r*.
   The precision of the result will be equal to the precision of *r*.

   :param r: the operand.

   :return: the cubic root of *r*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::rootn_ui(mppp::real &rop, T &&op, unsigned long k)

   .. versionadded:: 0.12

   .. note::
      This function is available from MPFR 4 onwards.

   Binary :cpp:class:`~mppp::real` k-th root.

   This function will compute the k-th root of *op* and store it
   into *rop*. The precision of the result will be equal to the precision
   of *op*.

   If *k* is zero, the result will be NaN. If *k* is odd (resp. even) and *op*
   negative (including negative infinity), the result will be a negative number (resp. NaN).
   If *op* is zero, the result will be zero with the sign obtained by the usual limit rules, i.e.,
   the same sign as *op* if *k* is odd, and positive if *k* is even.

   :param rop: the return value.
   :param op: the operand.
   :param k: the degree of the root.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::rootn_ui(T &&r, unsigned long k)

   .. versionadded:: 0.12

   .. note::
      This function is available from MPFR 4 onwards.

   Unary :cpp:class:`~mppp::real` k-th root.

   This function will compute and return the k-th root of *r*.
   The precision of the result will be equal to the precision
   of *r*.

   If *k* is zero, the result will be NaN. If *k* is odd (resp. even) and *r*
   negative (including negative infinity), the result will be a negative number (resp. NaN).
   If *r* is zero, the result will be zero with the sign obtained by the usual limit rules, i.e.,
   the same sign as *r* if *k* is odd, and positive if *k* is even.

   :param r: the operand.
   :param k: the degree of the root.

   :return: the k-th root of *r*.

.. _real_exponentiation:

Exponentiation
~~~~~~~~~~~~~~

.. cpp:function:: template <mppp::CvrReal T, mppp::CvrReal U> mppp::real &mppp::pow(mppp::real &rop, T &&op1, U &&op2)

   Ternary exponentiation.

   This function will set *rop* to *op1* raised to the power of *op2*.
   The precision of *rop* will be set to the largest precision among the operands.

   :param rop: the return value.
   :param op1: the base.
   :param op2: the exponent.

   :return: a reference to *rop*.

.. cpp:function:: template <typename T, typename U> mppp::real pow(T &&op1, U &&op2)

   .. note::

      This function participates in overload resolution only if ``T`` and ``U`` satisfy
      the :cpp:concept:`~mppp::RealOpTypes` concept.

   Binary exponentiation.

   This function will compute and return *op1* raised to the power of *op2*.
   The precision of the result will be set to the largest precision among the operands.

   Non-:cpp:class:`~mppp::real` operands will be converted to :cpp:class:`~mppp::real`
   before performing the operation. The conversion of non-:cpp:class:`~mppp::real` operands
   to :cpp:class:`~mppp::real` follows the same heuristics described in the generic assignment operator of
   :cpp:class:`~mppp::real`. Specifically, the precision of the conversion is either the default
   precision, if set, or it is automatically deduced depending on the type and value of the
   operand to be converted.

   :param op1: the base.
   :param op2: the exponent.

   :return: *op1* raised to the power of *op2*.

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

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sqr(mppp::real &rop, T &&op)

   .. versionadded:: 0.19

   Binary :cpp:class:`~mppp::real` squaring.

   This function will compute the square of *op* and store it
   into *rop*. The precision of the result will be equal to the precision
   of *op*.

   :param rop: the return value.
   :param op: the operand.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sqr(T &&r)

   .. versionadded:: 0.19

   Unary :cpp:class:`~mppp::real` squaring.

   This function will compute and return the square of *r*.
   The precision of the result will be equal to the precision of *r*.

   :param r: the operand.

   :return: the square of *r*.

.. _real_trig:

Trigonometry
~~~~~~~~~~~~

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sin(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::cos(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::tan(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sec(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::csc(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::cot(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sin_pi(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::cos_pi(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::tan_pi(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::cot_pi(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sinc(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sinc_pi(mppp::real &rop, T &&x)

   .. note::
      The functions ``sin_pi()``, ``cos_pi()``, ``tan_pi()``,
      ``cot_pi()``, ``sinc()`` and ``sinc_pi()`` are available only
      if mp++ was
      configured with the ``MPPP_WITH_ARB`` option enabled
      (see the :ref:`installation instructions <installation>`).

   Binary basic trigonometric functions.

   These functions will set *rop* to, respectively:

   * :math:`\sin\left( x \right)`,
   * :math:`\cos\left( x \right)`,
   * :math:`\tan\left( x \right)`,
   * :math:`\sec\left( x \right)`,
   * :math:`\csc\left( x \right)`,
   * :math:`\cot\left( x \right)`,
   * :math:`\sin\left( \pi x \right)`,
   * :math:`\cos\left( \pi x \right)`,
   * :math:`\tan\left( \pi x \right)`,
   * :math:`\cot\left( \pi x \right)`,
   * :math:`\frac{\sin\left( x \right)}{x}`,
   * :math:`\frac{\sin\left( \pi x \right)}{\pi x}`.

   The precision of the result will be equal to the precision of *x*.

   :param rop: the return value.
   :param x: the argument.

   :return: a reference to *rop*.

   :exception std\:\:invalid_argument: if the conversion between Arb and MPFR types
     fails because of (unlikely) overflow conditions.

   .. versionadded:: 0.19

      The functions ``sin_pi()``, ``cos_pi()``, ``tan_pi()``,
      ``cot_pi()``, ``sinc()`` and ``sinc_pi()``.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sin(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::cos(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::tan(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sec(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::csc(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::cot(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sin_pi(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::cos_pi(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::tan_pi(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::cot_pi(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sinc(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sinc_pi(T &&x)

   .. note::
      The functions ``sin_pi()``, ``cos_pi()``, ``tan_pi()``,
      ``cot_pi()``, ``sinc()`` and ``sinc_pi()`` are available only
      if mp++ was
      configured with the ``MPPP_WITH_ARB`` option enabled
      (see the :ref:`installation instructions <installation>`).

   Unary basic trigonometric functions.

   These functions will return, respectively:

   * :math:`\sin\left( x \right)`,
   * :math:`\cos\left( x \right)`,
   * :math:`\tan\left( x \right)`,
   * :math:`\sec\left( x \right)`,
   * :math:`\csc\left( x \right)`,
   * :math:`\cot\left( x \right)`,
   * :math:`\sin\left( \pi x \right)`,
   * :math:`\cos\left( \pi x \right)`,
   * :math:`\tan\left( \pi x \right)`,
   * :math:`\cot\left( \pi x \right)`,
   * :math:`\frac{\sin\left( x \right)}{x}`,
   * :math:`\frac{\sin\left( \pi x \right)}{\pi x}`.

   The precision of the result will be equal to the precision of *x*.

   :param x: the argument.

   :return: the trigonometric function of *x*.

   :exception std\:\:invalid_argument: if the conversion between Arb and MPFR types
     fails because of (unlikely) overflow conditions.

   .. versionadded:: 0.19

      The functions ``sin_pi()``, ``cos_pi()``, ``tan_pi()``,
      ``cot_pi()``, ``sinc()`` and ``sinc_pi()``.

.. cpp:function:: template <mppp::CvrReal T> void mppp::sin_cos(mppp::real &sop, mppp::real &cop, T &&op)

   Simultaneous sine and cosine.

   This function will set *sop* and *cop* respectively to the sine and cosine of *op*.
   *sop* and *cop* must be distinct objects. The precision of *sop* and *rop* will be set to the
   precision of *op*.

   :param sop: the sine return value.
   :param cop: the cosine return value.
   :param op: the operand.

   :exception std\:\:invalid_argument: if *sop* and *cop* are the same object.

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::asin(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::acos(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::atan(mppp::real &rop, T &&op)

   Binary basic inverse trigonometric functions.

   These functions will set *rop* to, respectively, the arcsine, arccosine and
   arctangent of *op*.
   The precision of the result will be equal to the precision of *op*.

   :param rop: the return value.
   :param op: the argument.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::asin(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::acos(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::atan(T &&r)

   Unary basic inverse trigonometric functions.

   These functions will return, respectively, the arcsine, arccosine and
   arctangent of *r*.
   The precision of the result will be equal to the precision of *r*.

   :param r: the argument.

   :return: the arcsine, arccosine or arctangent of *r*.

.. cpp:function:: template <mppp::CvrReal T, mppp::CvrReal U> mppp::real &mppp::atan2(mppp::real &rop, T &&y, U &&x)

   Ternary arctangent-2.

   This function will set *rop* to the arctangent-2 of *y* and *x*.
   The precision of *rop* will be set to the largest precision among the operands.

   :param rop: the return value.
   :param y: the sine argument.
   :param x: the cosine argument.

   :return: a reference to *rop*.

.. cpp:function:: template <typename T, mppp::RealOpTypes<T> U> mppp::real mppp::atan2(T &&y, U &&x)

   Binary arctangent-2.

   This function will compute and return the arctangent-2 of *y* and *x*.

   Non-:cpp:class:`~mppp::real` operands will be converted to :cpp:class:`~mppp::real`
   before performing the operation. The conversion of non-:cpp:class:`~mppp::real` operands
   to :cpp:class:`~mppp::real` follows the same heuristics described in the generic assignment
   operator of :cpp:class:`~mppp::real`. Specifically, the precision of the conversion is
   either the default precision, if set, or it is automatically deduced depending on the type
   and value of the operand to be converted.

   :param y: the sine argument.
   :param x: the cosine argument.

   :return: the arctangent-2 of *y* and *x*.

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

.. _real_hyper:

Hyperbolic functions
~~~~~~~~~~~~~~~~~~~~

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sinh(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::cosh(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::tanh(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::sech(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::csch(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::coth(mppp::real &rop, T &&op)

   Binary basic hyperbolic functions.

   These functions will set *rop* to, respectively, the hyperbolic sine, cosine, tangent, secant,
   cosecant and cotangent of *op*.
   The precision of the result will be equal to the precision of *op*.

   :param rop: the return value.
   :param op: the argument.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sinh(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::cosh(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::tanh(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::sech(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::csch(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::coth(T &&r)

   Unary basic hyperbolic functions.

   These functions will return, respectively, the hyperbolic sine, cosine, tangent,
   secant, cosecant and cotangent of *r*.
   The precision of the result will be equal to the precision of *r*.

   :param r: the argument.

   :return: the hyperbolic sine, cosine, tangent, secant, cosecant or cotangent of *r*.

.. cpp:function:: template <mppp::CvrReal T> void mppp::sinh_cosh(mppp::real &sop, mppp::real &cop, T &&op)

   Simultaneous hyperbolic sine and cosine.

   This function will set *sop* and *cop* respectively to the hyperbolic sine and cosine of *op*.
   *sop* and *cop* must be distinct objects. The precision of *sop* and *rop* will be set to the
   precision of *op*.

   :param sop: the hyperbolic sine return value.
   :param cop: the hyperbolic cosine return value.
   :param op: the operand.

   :exception std\:\:invalid_argument: if *sop* and *cop* are the same object.

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::asinh(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::acosh(mppp::real &rop, T &&op)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::atanh(mppp::real &rop, T &&op)

   Binary basic inverse hyperbolic functions.

   These functions will set *rop* to, respectively, the inverse hyperbolic sine, cosine and
   tangent of *op*.
   The precision of the result will be equal to the precision of *op*.

   :param rop: the return value.
   :param op: the argument.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::asinh(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::acosh(T &&r)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::atanh(T &&r)

   Unary basic inverse hyperbolic functions.

   These functions will return, respectively, the inverse hyperbolic sine, cosine and
   tangent of *r*.
   The precision of the result will be equal to the precision of *r*.

   :param r: the argument.

   :return: the inverse hyperbolic sine, cosine or tangent of *r*.

.. _real_logexp:

Logarithms and exponentials
~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::exp(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::exp2(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::exp10(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::expm1(mppp::real &rop, T &&x)

   Binary exponentials.

   These functions will set *rop* to, respectively,

   * :math:`e^x`,
   * :math:`2^x`,
   * :math:`10^x`,
   * :math:`e^x - 1`.

   The precision of the result will be equal to the precision of *x*.

   :param rop: the return value.
   :param x: the exponent.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::exp(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::exp2(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::exp10(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::expm1(T &&x)

   Unary exponentials.

   These functions will return, respectively,

   * :math:`e^x`,
   * :math:`2^x`,
   * :math:`10^x`,
   * :math:`e^x - 1`.

   The precision of the result will be equal to the precision of *x*.

   :param x: the exponent.

   :return: the exponential of *x*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::log(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::log2(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::log10(mppp::real &rop, T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real &mppp::log1p(mppp::real &rop, T &&x)

   Binary logarithms.

   These functions will set *rop* to, respectively,

   * :math:`\log x`,
   * :math:`\log_2 x`,
   * :math:`\log_{10} x`,
   * :math:`\log\left( 1+x \right)`.

   The precision of the result will be equal to the precision of *x*.

   :param rop: the return value.
   :param x: the operand.

   :return: a reference to *rop*.

.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::log(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::log2(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::log10(T &&x)
.. cpp:function:: template <mppp::CvrReal T> mppp::real mppp::log1p(T &&x)

   Unary logarithms.

   These functions will return, respectively,

   * :math:`\log x`,
   * :math:`\log_2 x`,
   * :math:`\log_{10} x`,
   * :math:`\log\left( 1+x \right)`.

   The precision of the result will be equal to the precision of *x*.

   :param x: the operand.

   :return: the logarithm of *x*.

.. cpp:function:: template <mppp::CvrReal T, mppp::CvrReal U> mppp::real &mppp::log_hypot(mppp::real &rop, T &&x, U &&y)

   .. versionadded:: 0.19

   .. note::
      This function is available only if mp++ was
      configured with the ``MPPP_WITH_ARB`` option enabled
      (see the :ref:`installation instructions <installation>`).

   Ternary log hypot function.

   This function will set *rop* to :math:`\log\left(\sqrt{x^2+y^2}\right)`.
   The precision of *rop* will be set to the largest precision among the operands.

   :param rop: the return value.
   :param x: the first argument.
   :param y: the second argument.

   :return: a reference to *rop*.

   :exception std\:\:invalid_argument: if the conversion between Arb and MPFR types
     fails because of (unlikely) overflow conditions.

.. cpp:function:: template <typename T, typename U> mppp::real mppp::log_hypot(T &&x, U &&y)

   .. versionadded:: 0.19

{'fraction_non_alphanumeric': 0.1569770629626245, 'fraction_numerical': 0.004569130951293064, 'mean_word_length': 3.8000701815948768, 'pattern_counts': {'":': 0, '<': 205, '<?xml version=': 0, '>': 205, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3698811', 'n_tokens_mistral': 19987, 'n_tokens_neox': 19197, 'n_words': 6539}