Very Large Numbers in R.
Very large numbers in R: the Brobdingnag package
Overview
The Brobdingnag package provides R-centric functionality for working with very large numbers. It represents a number as its logarithm together with a logical that indicates whether is positive. The vignette functions as a “hello world” for S4 methods.
The package has functionality to represent Brobdingnagian matrices, and complex numbers.
Installation
You can install the released version of Brobdingnag from CRAN with:
# install.packages("Brobdingnag") # uncomment this to use the package
library("Brobdingnag")
#>
#> Attaching package: 'Brobdingnag'
#> The following objects are masked from 'package:base':
#>
#> diag, max, min, prod, range, sum, t
The package is maintained on github.
The Brobdingnag
package in use
Consider a googol, conventionally defined as . In standard arithmetic we may evaluate this as follows:
10^100
#> [1] 1e+100
But a googolplex, , is beyond floating-point representation:
10^(10^100)
#> [1] Inf
We may represent a googol straightforwardly using Brobdingnagian arithmetic, specifically by working with brob
objects.
as.brob(10)
#> [1] +exp(2.3026)
googol <- as.brob(10)^100
googol
#> [1] +exp(230.26)
10^googol
#> [1] +exp(2.3026e+100)
In the above, we coerce 10
to Brobdingnagian form (that is, an object of class brob
) using as.brob()
. Most arithmetic methods work transparently with Brobdingnagian numbers:
googol
#> [1] +exp(230.26)
googol + googol
#> [1] +exp(230.95)
googol/10
#> [1] +exp(227.96)
1/googol
#> [1] +exp(-230.26)
sqrt(googol)
#> [1] +exp(115.13)
exp(googol)
#> [1] +exp(1e+100)
Note that precision may be adversely affected for very large numbers:
gplex <- 10^googol
gplex
#> [1] +exp(2.3026e+100)
gplex - gplex/10
#> [1] -exp(-Inf)
The last line looks odd [the return value is package idiom for zero] but symbolically we have . The package is vectorised and allows Brobdingnagian arithmetic:
googol/(1:20)
#> [1] +exp(230.26) +exp(229.57) +exp(229.16) +exp(228.87) +exp(228.65)
#> [6] +exp(228.47) +exp(228.31) +exp(228.18) +exp(228.06) +exp(227.96)
#> [11] +exp(227.86) +exp(227.77) +exp(227.69) +exp(227.62) +exp(227.55)
#> [16] +exp(227.49) +exp(227.43) +exp(227.37) +exp(227.31) +exp(227.26)
Signed quantities operate as expected:
as.brob(5) - 1:10
#> [1] +exp(1.3863) +exp(1.0986) +exp(0.69315) +exp(-2.2204e-16)
#> [5] -exp(-Inf) -exp(4.4409e-16) -exp(0.69315) -exp(1.0986)
#> [9] -exp(1.3863) -exp(1.6094)
It is a semi-nonobvious fact that, in addition to large numbers (that is, and small numbers (), the package can deal with numbers very close to 1 (that is, ). Suppose we wish to deal with . In the package:
a <- brob(1e-100)
a
#> [1] +exp(1e-100)
a^googol
#> [1] +exp(1)
The last line being numerical verification of the fact that . The package also includes some functionality for Brobdingnagian matrices:
brobmat(1:9,3,3)
#> [,1] [,2] [,3]
#> [1,] +exp(1) +exp(4) +exp(7)
#> [2,] +exp(2) +exp(5) +exp(8)
#> [3,] +exp(3) +exp(6) +exp(9)
brobmat(1:9,3,3) %*% 10^brobmat(9:1,3,3)
#> [,1] [,2] [,3]
#> [1,] +exp(18659) +exp(929.93) +exp(47.249)
#> [2,] +exp(18660) +exp(930.93) +exp(48.249)
#> [3,] +exp(18661) +exp(931.93) +exp(49.249)