Elementary functions of balls
#include <flint/mp_real.h>Set res1 and res2 to balls containing and for every in . Either output may be NULL. The sine keeps its relative accuracy for small ; near the other zeros the loss of significance shows in the radius. Arguments with give .
If is inexact, prec is first lowered to a few bits beyond the accuracy its radius allows (relative for , absolute otherwise), and the radius is added to both outputs at the end (as ). A ball inside whose radius exceeds a quarter of its midpoint gives and for ; a wider ball elsewhere gives .
For a midpoint with leading zero bits (): if the results are and 1, and if they are and , with the Taylor remainders in the radius. Otherwise, for , the fixed-point kernel is called on at bits plus guard bits (or a series for the reduced argument when is large). For the argument is reduced modulo , with the quotient chosen so that the remainder is nonnegative, folded to , and the outputs are permuted and negated according to the quotient modulo 4. The reduction adds at most 3 ulps to the kernel's bound and is not repeated at a higher precision near zeros.
Set res to a ball containing for every in and return 1, or return 0 with res set to zero when the ball may contain a pole (or ). The result keeps its relative accuracy near the zeros and poles of the tangent.
After the reduction , , the result is for even and for odd (one Newton reciprocal). Near a zero or a pole is small, so the kernel runs with the leading zero bits of as extra precision, and the reduction is repeated at that precision when the first pass had fewer limbs. An exact is never a multiple of , and by the irrationality measure of a -bit lies at least about away from one; the repetition is capped at extra bits (status 0 beyond). For an inexact no repetition is made once falls below the radius.
The radius of enters through a pole test: with enclosing and , implies that the ball contains no pole, and then .
The same as mp_real_sin_cos_bits and mp_real_tan_bits for , and . The argument reduction is exact, so the outputs keep their relative accuracy near every zero (and the tangent near every pole) at any magnitude of , and the values at multiples of (and of the tangent at odd multiples of ) are exact.
The midpoint is dyadic, and its units bit and fraction bits give with , and exactly. Then enters the formulas of the reduction modulo ; gives or (and a pole of the tangent for odd , status 0), and the exact . Otherwise has leading zero bits and the kernel runs at extra bits. The radius of is a radius of the argument; gives for the sine and cosine.
Set res1 and res2 to balls containing and , respectively res to , for words and , to a relative accuracy of about . Either output of the first function may be NULL; the two must be distinct. The tangent returns 0 with res set to zero at a pole, else 1. The rational values are exact. Both throw for .
The fraction is reduced to lowest terms and folded by the symmetries to with . The nonzero values of and are at least , so _mp_real_sin_cos_pi_ui_div_ui at limbs gives the relative accuracy. The tangent uses the closed forms , , , for and , for (from 12 limbs), the Chebyshev sine and cosine and one division for the denominators where they win, and the tangent kernel otherwise.
Set res to a ball containing , resp. for every in . The results keep their relative accuracy near , and . mp_real_exp_bits throws for , where the exponent of the result would leave the safe range. mp_real_log_bits returns 0 with res set to zero unless the ball is strictly positive, and 1 otherwise.
The radius of enters as the factor (exp), as (log, by the mean value theorem), and as , or when the ball stays beyond 1 in absolute value (atan). An exp ball too wide for two correct bits gives .
- exp: , , with from two limbs of and one multiply-subtract by ; for the quotient is rounded up and the remainder complemented, so that directly. Small use , , ... or a series for the reduced argument.
- log: with , , up to 600 limbs and by
_mp_real_neglog_newtonabove; near 1, for , or the first terms of . - atan: for , , and for ; .
At few limbs the per-size kernels are called directly on the argument's limbs in place.
Set res (rs to and rc to , either may be NULL) to a ball containing , , , , , , , , resp. for every in . The results keep their relative accuracy at the zeros of the functions, and tiny and huge arguments are handled without squaring them. The functions returning int return 0 with res set to zero when the ball is not certified to lie in the domain, and 1 otherwise.
The domains are: for log1p, for atanh, and for asin, acos and acosh resp. for an exact argument and strictly inside for an inexact one. mp_real_expm1_bits throws like mp_real_exp_bits for , and mp_real_sinh_cosh_bits for ; expm1 of a large negative argument gives with a tiny radius.
The functions are compositions of mp_real_exp_bits, mp_real_log_bits and mp_real_atan_bits by formulas without cancellation: with formed exactly (or to bits for ); from at bits; and from ; ; and with exact; ; with exact; and . Tiny and huge arguments use the leading terms with a bounded remainder (, , ), and , and are exact. The radius enters through a bound for the variation over the ball, for example for and for atanh.
Set res to a ball containing for every in , to a relative accuracy of about , without the precomputed tables of mp_real_exp_bits. These are meant for a single exponential at huge precision, where building the tables does not pay. The ball handling and the range are those of mp_real_exp_bits.
mp_real_exp_notab_log2reduces by (computing and caching ) and calls_mp_real_exp_notab; it is the fastest when is already cached.mp_real_exp_notab_squaringneeds no : with , the reduced value from_mp_real_exp_notaband ball squarings (with guard bits), and one reciprocal for . It is faster than the reduction when must be computed.mp_real_exp_agmcomputes to a fraction of the precision by the squarings and corrects it by one Newton–Taylor step on the AGM logarithm of (Elementary functions in mp_real), in . It calls the squarings below about 30 limbs and overtakes them at about 15000 limbs.
These functions evaluate exp, log, the trigonometric and hyperbolic functions and their inverses on mp_real_t balls. They take a target precision in bits rather than limbs and choose their working precision themselves, so that the result has a relative accuracy of about whenever the argument allows it.
Common behaviour#
- Midpoint and radius. The midpoint of the argument is evaluated exactly as given, with all its limbs, and the radius is propagated at the end through a bound for the variation of the function over the ball (for exp, the factor ; for log, ). When the radius limits the accuracy,
precis first lowered to a few bits beyond what the radius allows, so that no time is spent on digits the radius would swamp. - Relative accuracy near zeros. The results keep their relative accuracy where the function value is small: near 0 (through
mp_real_expm1_bits), near 1, , , , , , , and near 0, and near 1. The argument reduction adds the leading zero bits of the reduced argument to the working precision. The functions of reduce exactly and keep relative accuracy near every zero; and near nonzero multiples of show the cancellation of the reduction in their radius instead. - Domains. The functions with a restricted domain return an
int: 1 on success, or 0 with the output set to zero when the ball is not certified to lie in the domain (a log of a ball containing 0, an asin of a ball reaching beyond , a tangent of a ball that may contain a pole). The functions without a status throw where the result's exponent would leave the safe range: for . - Aliasing. Outputs may alias the argument. Where a function has two outputs (
mp_real_sin_cos_bits,mp_real_sinh_cosh_bits), either may beNULL. - Huge arguments. The sine, cosine and tangent give , resp. status 0, for , where the reduction modulo would need more bits of than is reasonable.
The functions with explicit precisions in limbs, mp_real_sin_cos_pi_ui_div_ui, mp_real_tan_pi_ui_div_ui and the table-free exponentials, follow the same conventions with in place of .
Algorithms#
Each function reduces the argument to a fixed-point number in (by for exp, by the exponent for log, by for the trigonometric functions, exactly by for the functions of , and to for atan) and calls the kernel for the working size: table-driven kernels up to three limbs, dense-table kernels up to 32 limbs, bitwise reduction up to 600 limbs, multi-prime (diophantine) reduction up to 65536 limbs (Newton–Taylor inversion of it for log and atan), and table-free bit-burst evaluation beyond. The hyperbolic and inverse functions are compositions of exp, log and atan arranged to avoid cancellation. The guide Fixed-point kernels lists the kernels, and Elementary functions in mp_real describes them.
AlgorithmElementary functions in mp_realHow mp_real evaluates exp, log, the trigonometric functions and their inverses from one limb to millions of limbs: argument reduction of balls, table-driven and dense-table kernels, bitwise (BKM-type) reduction with signed digits, rectangular splitting, bit-burst evaluation, Newton–Taylor inversion, the AGM logarithm, and sines of rational multiples of π.Example#
#include <flint/flint.h>
#include <flint/mp_real.h>
#include <flint/arb.h>
static void show(const char * name, const mp_real_t x)
{
arb_t a;
arb_init(a);
mp_real_get_arb(a, x);
flint_printf("%s = ", name);
arb_printn(a, 30, 0);
flint_printf("\n");
arb_clear(a);
}
int main(void)
{
mp_real_t x, s, c, y;
int ok;
mp_real_init(x);
mp_real_init(s);
mp_real_init(c);
mp_real_init(y);
/* x = 3/2 exactly */
mp_real_set_ui(x, 3);
mp_real_mul_2exp_si(x, x, -1);
mp_real_exp_bits(y, x, 100);
show("exp(3/2)", y);
mp_real_log_bits(y, x, 100);
show("log(3/2)", y);
mp_real_sin_cos_bits(s, c, x, 100);
show("sin(3/2)", s);
show("cos(3/2)", c);
ok = mp_real_tan_bits(y, x, 100);
flint_printf("tan status %d\n", ok);
show("tan(3/2)", y);
/* x = 1/2 + 2^-200: cos(pi x) keeps its relative accuracy */
mp_real_set_ui(x, 1);
mp_real_mul_2exp_si(x, x, -200);
mp_real_set_ui(y, 1);
mp_real_mul_2exp_si(y, y, -1);
mp_real_add(x, x, y, 10);
mp_real_sin_cos_pi_bits(s, c, x, 100);
show("sin(pi x)", s);
show("cos(pi x)", c);
/* a ball containing 0 is outside the domain of log */
mp_real_set_si(x, -1);
mp_real_add_error_2exp_si(x, 1);
ok = mp_real_log_bits(y, x, 100);
flint_printf("log status %d\n", ok);
mp_real_set_ui(x, 1);
mp_real_mul_2exp_si(x, x, -1);
mp_real_atanh_bits(y, x, 100);
show("atanh(1/2)", y);
mp_real_clear(x);
mp_real_clear(s);
mp_real_clear(c);
mp_real_clear(y);
flint_cleanup_master();
return 0;
}exp(3/2) = [4.48168907033806482260205546012 +/- 7.25e-31] log(3/2) = [0.405465108108164381978013115464 +/- 3.50e-31] sin(3/2) = [0.997494986604054430941723371141 +/- 4.88e-31] cos(3/2) = [0.0707372016677029100881898514343 +/- 3.13e-32] tan status 1 tan(3/2) = [14.1014199471717193876460836520 +/- 1.23e-29] sin(pi x) = [1.00000000000000000000000000000 +/- 4.64e-69] cos(pi x) = [-1.95501790801056086750878985681e-60 +/- 9.48e-93] log status 0 atanh(1/2) = [0.549306144334054845697622618461 +/- 2.63e-31]
The value is about and is computed with a relative error of about , although the argument itself has 200 bits.
Guides#
The FLINT team, “Elementary functions of balls (mp_real.h),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/mp_real/elementary.html (generated 2026-11-02).
@misc{flint-doc-mp-real-elementary,
author = {{The FLINT team}},
title = {{Elementary functions of balls (mp\_real.h)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/mp_real/elementary.html},
note = {Generated 2026-11-02}
}