FLINT3.7.0-dev

Decimal input and output

Synopsis#include <flint/arb.h>
int arb_set_str(arb_t res, const char * inp, slong prec)source

Sets res to a ball containing the number described by the decimal string inp, rounded to prec bits, and returns 0 on success. Accepted forms are a decimal literal ("25", "0.001", "7e+141", "-31.4159e-1"), a ball "[3.25 +/- 0.0001]" (brackets optional) and "[+/- 10]", as well as "inf", "-inf" and "nan".

The conversion is rigorous: the error of the binary approximation of the decimal midpoint and radius is added to the radius, so the result contains the exact decimal value. A NaN midpoint gives an indeterminate ball. On a parse error the function returns nonzero and sets res to an indeterminate ball. The output of arb_get_str with default flags can be read back with this function.

char * arb_get_str(const arb_t x, slong n, ulong flags)source

Returns a decimal string for x, to be freed with flint_free, with at most n significant digits of the midpoint. By default it has the form [m +/- r] with an m that is correct to within one unit in its last digit and an r such that the decimal ball contains x; the string can be read back with arb_set_str.

With ARB_STR_MORE, more (possibly incorrect) digits may be printed. With ARB_STR_NO_RADIUS the radius is omitted; unless ARB_STR_MORE is also set, the midpoint is still rounded so that it is correct to one unit in the last place, and if no digit is significant the result is shown as 0e+n, meaning a number between -10^n and 10^n. Adding m times ARB_STR_CONDENSE to flags condenses runs of more than 3m digits, printing the first and last m digits and the number of omitted digits in brackets.

The conversion is done exactly (through the decimal module): the midpoint is correctly rounded to the printed number of digits (to nearest, with ties away from zero), the number of digits is the largest for which the printed radius is at most one unit in the last place, and the printed radius is the true radius plus the exact rounding error, rounded up to three significant digits. In particular, an exact midpoint that is exactly representable with n digits is printed without a radius (arb_get_str of the exact integer 10^{100} with n = 31 gives 1.000000000000000000000000000000e+100), and a tiny radius is never inflated ([1 \pm 2^{-1000}] prints as [1.00000000000000000000000000000 +/- 9.34e-302] with n = 30). Arguments with huge exponents are handled by scaling with a power of ten computed in ball arithmetic, which cannot decide whether the value is an exact decimal number; an exact midpoint with a huge exponent is therefore tested for exact representability directly.

void arb_printn(const arb_t x, slong digits, ulong flags)source
void arb_fprintn(FILE * file, const arb_t x, slong digits, ulong flags)source

Print the string of arb_get_str to standard output or to file. This is the recommended way to print a ball.

void arb_printd(const arb_t x, slong digits)source
void arb_fprintd(FILE * file, const arb_t x, slong digits)source

Print the midpoint and the radius as decimal floating-point numbers with digits and 5 significant digits, in the form m +/- r. The decimal values are approximations: the printed interval need not contain x.

void arb_print(const arb_t x)source
void arb_fprint(FILE * file, const arb_t x)source

Print the exact binary representation of x as (m * 2^e) +/- (r * 2^f).

Balls are stored in binary, but are usually read and written in decimal. Converting between the two is inexact in general, and FLINT provides conversions that take the conversion error into account, so that a decimal string obtained from a ball, or a ball obtained from a decimal string, is still a rigorous enclosure.

The decimal ball format#

arb_get_str and arb_printn produce a decimal ball [m +/- r] whose midpoint m has at most n significant digits and whose radius r has three. The guarantee is that the decimal interval [m - r, m + r] contains the binary ball, so it can be read back with arb_set_str without loss of rigour. By default only digits that are correct up to one unit in the last place are printed: the number of digits is the largest for which the printed radius, including the error of rounding the midpoint to that many digits, is at most one unit in the last digit. Consequently

  • an exact ball whose value has at most n significant digits is printed without radius, for example 0 or 1.5 or 1.000000000000000000000000000000e+100;
  • a ball with a tiny radius is printed with the radius it has, not with the rounding error of the last printed digit: [1 \pm 2^{-1000}] at 30 digits gives [1.00000000000000000000000000000 +/- 9.34e-302];
  • a ball without a single correct digit is printed as [+/- r];
  • an indeterminate ball is printed as nan, and any ball with an infinite midpoint or radius as [+/- inf], which drops the sign of an infinite midpoint (the string is still a valid enclosure).

The flags change this behaviour. ARB_STR_MORE prints up to n digits even if they are not all correct (the radius still makes the output rigorous). ARB_STR_NO_RADIUS omits the radius; the digits printed are still correct to one unit in the last place, and a ball with no correct digit is printed as 0e+n, meaning a number of absolute value below 10^n. A multiple k of ARB_STR_CONDENSE abbreviates runs of more than 3k digits.

Examplearb_printing.cchecked by make checkdoc
#include <flint/flint.h>
#include <flint/arb.h>

int main(void)
{
    arb_t x, y;
    char * s;

    arb_init(x); arb_init(y);

    arb_const_pi(x, 100);
    arb_div_ui(x, x, 1000, 100);

    arb_printn(x, 10, 0);                  flint_printf("\n");
    arb_printn(x, 50, 0);                  flint_printf("\n");
    arb_printn(x, 50, ARB_STR_MORE);       flint_printf("\n");
    arb_printn(x, 10, ARB_STR_NO_RADIUS);  flint_printf("\n");
    arb_printd(x, 10);                     flint_printf("\n");
    arb_print(x);                          flint_printf("\n");

    /* a wide ball: only the first digit is certain */
    arb_set_str(y, "[3.14 +/- 0.2]", 53);
    arb_printn(y, 10, 0);                  flint_printf("\n");
    arb_printn(y, 10, ARB_STR_NO_RADIUS);  flint_printf("\n");

    /* round trip through a decimal string */
    s = arb_get_str(x, 20, 0);
    arb_set_str(y, s, 100);
    flint_printf("%s -> contains x: %d\n", s, arb_contains(y, x));
    flint_free(s);

    /* condensed output of a long number */
    arb_const_pi(x, 3000);
    arb_printn(x, 900, ARB_STR_CONDENSE * 10); flint_printf("\n");

    arb_clear(x); arb_clear(y);
    flint_cleanup();
    return 0;
}
Output
[0.003141592654 +/- 4.11e-13]
[0.00314159265358979323846264338328 +/- 7.52e-33]
[0.0031415926535897932384626433832771392962513160822984 +/- 4.66e-33]
0.003141592654
0.003141592654 +/- 4.6592e-33
(1019505104126898525104217885171 * 2^-108) +/- (811748820 * 2^-137)
[3e+0 +/- 0.341]
3e+0
[0.0031415926535897932385 +/- 3.74e-23] -> contains x: 1
[3.1415926535{...879 digits...}7766914730 +/- 3.61e-900]

The first line shows how the radius absorbs the rounding of the midpoint to 10 digits: the binary ball has radius 4.7 \cdot 10^{-33}, but the decimal ball needs 4.11 \cdot 10^{-13}. At 50 digits only 33 are certain, and ARB_STR_MORE shows the remaining digits of the binary midpoint. The wide ball [3.14 \pm 0.2] has a single certain digit; the radius 0.341 covers both the original radius and the distance from 3.14 to 3.

Other output functions#

arb_printd prints decimal approximations of the midpoint and the radius (with 5 digits). It is cheap and shows the binary radius directly, but the printed interval is not guaranteed to contain the ball. arb_print prints the exact binary representation (m * 2^e) +/- (r * 2^f) with integer mantissas, which is what to look at when debugging. arb_dump_str and arb_load_str serialise a ball exactly in a compact hexadecimal format, for storing values and reading them back without any rounding.

Reading decimal input#

arb_set_str accepts plain decimal numbers ("0.1", "-7e+141"), balls in the output format above ("[0.1 +/- 1e-20]", also without the brackets, or "[+/- 1e-20]"), and "inf", "-inf" and "nan". The midpoint and the radius are converted rigorously: the result is a ball with a prec-bit midpoint that contains the decimal ball. It returns 0 on success; on a syntax error it returns nonzero and sets the ball to an indeterminate value.

To enter a decimal constant, arb_set_str is the right tool, while arb_set_d with a C literal such as 0.1 gives the binary double nearest to it, a different number:

arb_set_str(x, "0.1", prec);   /* a ball containing 1/10 */
arb_set_d(x, 0.1);             /* exactly 0.1000000000000000055511151231257827... */

Rational numbers can also be entered exactly with arb_set_fmpq or by dividing integers, for example arb_set_ui(x, 1); arb_div_ui(x, x, 10, prec).

Guides#

Cite this page

The FLINT team, “Decimal input and output (arb.h),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/arb/printing.html (generated 2026-10-20).