# Control the displayed precision

The `biginteger()` and `bigfloat()` vectors are capable of storing numeric data at very high precision. Showing the full precision can quickly become overwhelming, so bignum provides tools to control the precision displayed in the console.

These tools were strongly inspired by how the excellent pillar package formats base R numeric vectors – in particular `vignette("digits", package = "pillar")` and `vignette("numbers", package = "pillar")`. Indeed, this vignette follows the structure of those vignettes. Standing on the shoulders of giants…

    library(bignum)
    library(pillar)

## Standalone vectors

### Default formatting

Similar to pillar, the default formatting of bignum vectors is determined by two options.

- The `"bignum.sigfig"` option controls the number of significant figures (digits) displayed. The default value is 7.
- The `"bignum.max_dec_width"` option controls how wide the decimal notation can become before switching to scientific notation. The default value is 13.

To demonstrate the default formatting, here are the first 7 significant figures of pi:

    bigpi
    #> <bigfloat[1]>
    #> [1] 3.141593

We can increase the displayed precision via the `"bignum.sigfig"` option:

    options(bignum.sigfig = 10)
    bigpi
    #> <bigfloat[1]>
    #> [1] 3.141592654

Formatting using significant figures controls the total number of digits displayed (before and after the decimal point), but it will always show every digit before the decimal point.

    options(bignum.sigfig = 3)
    bigfloat(1.2345 * 10^(-1:4))
    #> <bigfloat[6]>
    #> [1] 0.123 1.23  12.3  123.  1235. 12345

An important exception is that terminal zeros are only shown if there are non-zero digits beyond the displayed significant figures.

    options(bignum.sigfig = 7)
    bigfloat(1 + c(0, 1e-3, 1e-7))
    #> <bigfloat[3]>
    #> [1] 1        1.001    1.000000

The `"bignum.max_dec_width"` option controls how wide the output can be (including the decimal point) before it switches to scientific notation. It makes the decision based on the widest value in the vector.

    bigfloat(1234567890123)
    #> <bigfloat[1]>
    #> [1] 1234567890123

    bigfloat(1234567890123.4)
    #> <bigfloat[1]>
    #> [1] 1.234568e+12

    bigfloat(12345678901234)
    #> <bigfloat[1]>
    #> [1] 1.234568e+13

### Custom formatting

Sometimes you want more specific formatting, or to apply formatting to a single vector without changing global options. This is achieved using the `format()` function (see `help("bignum-format")`).

The default formatting demonstrated above chooses between decimal and scientific notation, depending on how wide the output is and the `"bignum.max_dec_width"` option. The `format()` function provides a `notation` argument to override this decision.

    x <- bigfloat(1.2345 * 10^(-1:4))

    format(x, notation = "dec")
    #> [1] "0.12345" "1.2345"  "12.345"  "123.45"  "1234.5"  "12345"

    format(x, notation = "sci")
    #> [1] "1.2345e-01" "1.2345e+00" "1.2345e+01" "1.2345e+02" "1.2345e+03"
    #> [6] "1.2345e+04"

The default formatting also decides the total number of digits to show based on the `"bignum.sigfig"` option. The `format()` function supports overriding this value using the `sigfig` argument.

    format(x, sigfig = 3)
    #> [1] "0.123" "1.23"  "12.3"  "123."  "1235." "12345"

But `format()` also supports specifying how many digits to display after the decimal point, using the `digits` argument. If the value is positive, we show exactly that many digits. If the value is negative, we show at most that many digits (i.e. terminal zeros can be hidden).

    format(x, digits = 2)
    #> [1] "0.12"     "1.23"     "12.35"    "123.45"   "1234.50"  "12345.00"

    format(x, digits = -2)
    #> [1] "0.12"   "1.23"   "12.35"  "123.45" "1234.5" "12345"

## Tibble columns

The tibble package allows bignum vectors to be stored in a data frame. When a tibble is printed, the vector values are displayed vertically as a column. Consequently, the default formatting is adjusted to make the data easier to read vertically.

When stored as a tibble column, the bignum vector formatting consults two options. Note: These options are different from those used for formatting standalone vectors, because they reside within the pillar package (see `help("pillar-package")`).

- The `"pillar.sigfig"` option controls the number of significant figures (digits) displayed. The default value is 3.
- The `"pillar.max_dec_width"` option controls how wide the decimal notation can become before switching to scientific notation. The default value is 13.

We use the `pillar()` function to demonstrate tibble columns without the overhead of the tibble package.

    pillar(x)
    #> <pillar>
    #>  <bigflt>
    #>     0.123
    #>     1.23
    #>    12.3
    #>   123.
    #>  1235.
    #> 12345

We can increase the displayed precision via the `"pillar.sigfig"` option:

    options(pillar.sigfig = 4)
    pillar(x)
    #> <pillar>
    #>   <bigflt>
    #>     0.1235
    #>     1.235
    #>    12.35
    #>   123.4
    #>  1235.
    #> 12345

Since the formatted data is aligned on the decimal point, the `"pillar.max_dec_width"` option works differently from `"bignum.max_dec_width"`. One row might have many digits on the left of the point, and another row might have many digits on the right of the point (see example above). The total width calculation accounts for both extremes.

    options(pillar.max_dec_width = 9)
    pillar(x)
    #> <pillar>
    #> <bigflt>
    #> 1.235e-1
    #> 1.235e+0
    #> 1.235e+1
    #> 1.234e+2
    #> 1.234e+3
    #> 1.234e+4