This vignette follows terminology outlined by the vctrs package. For further
information, see
help("faq-compatibility-types", package = "vctrs")
.
There are three numeric types in base R: logical
,
integer
and double
. They form a natural
hierarchy from the simplest (logical
) to the richest
(double
), with richer types able to accommodate simpler
types without losing information.
integer
expands the set of integer values supported by
logical
.double
expands the set of integer values supported by
integer
, and also supports non-integer
values.The bignum package provides two additional numeric types:
biginteger
and bigfloat
. These are
type-compatible with the existing numeric types because they extend the
set of possible values. However, the hierarchy becomes more complex
because lossy casts are now possible.
biginteger
expands the set of integer values supported
by double
. In fact, it supports any integer value
(because biginteger
uses arbitrary precision). But it
does not support non-integer values.bigfloat
expands the set of values supported by
double
(both in precision and range), but does not
support the entire range of integers supported by
biginteger
(because bigfloat
uses fixed
precision).As discussed above, casting values from one type to another can lose information.
We see an example in base R, when we cast a non-integer or large
double
to an integer
:
# non-integer double
as.integer(1.5)
#> [1] 1
# large double
as.integer(1e10)
#> Warning: NAs introduced by coercion to integer range
#> [1] NA
For illustrative purposes, we now consider how lossy casts can affect bignum conversions:
library(bignum)
# double -> biginteger
as_biginteger(1.5)
#> Warning: Loss of precision while converting from `x` <double> to <biginteger>.
#> • Locations: 1
#> <biginteger[1]>
#> [1] 1
# biginteger -> double
as.double(biginteger(10)^16L)
#> Warning: Loss of precision while converting from `x` <biginteger> to <double>.
#> • Locations: 1
#> [1] 1e+16
# bigfloat -> double
as.double(bigfloat(1) / 3)
#> Warning: Loss of precision while converting from `x` <bigfloat> to <double>.
#> • Locations: 1
#> [1] 0.3333333
# bigfloat -> biginteger
as_biginteger(bigfloat(1.5))
#> Warning: Loss of precision while converting from `x` <bigfloat> to <biginteger>.
#> • Locations: 1
#> <biginteger[1]>
#> [1] 1
# biginteger -> bigfloat
as_bigfloat(biginteger(10)^51L + 1L)
#> Warning: Loss of precision while converting from `x` <biginteger> to <bigfloat>.
#> • Locations: 1
#> <bigfloat[1]>
#> [1] 1e+51