Base R provides two data types that can store integers: integer and
double (also known as numeric). The former is a fixed-point data
format (32-bit) and the latter is a floating-point data format (64-bit).
Both types are signed, and R does not offer unsigned variants.
For the purpose of storing IP addresses as integers, we need to be able to
store a large range of positive integers without losing integer precision.
Under these circumstances, the integer type can store integers up to
2^31 - 1 and the double type can store integers up to 2^53. However,
for IPv4 and IPv6 addresses we need to store integers up to 2^32 - 1 and
2^128 - 1, respectively. This means an IPv4 address can be stored in a
double, but an IPv6 address cannot be stored in either R data type.
Although the integer representation of an IPv6 address cannot be stored in
a numeric R data type, it can be stored as a character string instead.
This allows the integer to be written to disk or used by other software that
does support 128-bit unsigned integers. To treat IPv4 and IPv6 equally,
ip_to_integer() will always return a character vector. With IPv4
addresses, this output can be converted to a double vector using
as.double() or as.numeric(). With IPv6 addresses, this conversion loses
the distinction between individual addresses because integer precision is lost.