Digit/Bit Representation of Integers in any Base
digitsBase.RdInteger number representations in other Bases.
Formally, for every element \(N =\)x[i], compute the (vector
of) “digits” \(A\) of the base \(b\)
representation of the number \(N\), \(N = \sum_{k=0}^M A_{M-k} b ^ k\).
Revert such a representation to integers.
Usage
digitsBase(x, base = 2, ndigits = 1 + floor(1e-9 + log(max(x,1), base)))
# S3 method for class 'basedInt'
as.integer(x, ...)
# S3 method for class 'basedInt'
print(x, ...)
as.intBase(x, base = 2)
bi2int(xlist, base)Arguments
- x
For
digitsBase(): non-negative integer (vector) whose basebasedigits are wanted.For
as.intBase():
a list of numeric vectors, a character vector, or an integer matrix as returned bydigitsBase(), representing digits in basebase.- base
integer, at least 2 specifying the base for representation.
- ndigits
number of bits/digits to use.
- ...
potential further arguments passed to methods, notably
print.- xlist
a
listof integer vectors with entries typically in0:(base-1), such as resulting fromdigitsBase().
Value
For digitsBase(), an object, say m, of class
"basedInt" which is basically a (ndigits x n)
matrix where m[,i] corresponds to x[i],
n <- length(x) and attr(m,"base") is the input
base.
as.intBase() and the as.integer method for
basedInt objects return an integer vector.
bi2int() is the low-level workhorse of as.intBase().
Note
Some of these functions existed under names digits and
digits.v in previous versions of the sfsmisc package.
Examples
digitsBase(0:12, 8) #-- octal representation
#> Class 'basedInt'(base = 8) [1:13]
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
#> [1,] 0 0 0 0 0 0 0 0 1 1 1 1 1
#> [2,] 0 1 2 3 4 5 6 7 0 1 2 3 4
empty.dimnames(digitsBase(0:33, 2)) # binary
#> Class 'basedInt'(base = 2) [1:34]
#>
#> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
#> 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0
#> 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0
#> 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0
#> 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0
#> 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
## This may be handy for just one number (and default decimal):
digits <- function(n, base = 10) as.vector(digitsBase(n, base = base))
digits(128982734) # 1 2 8 9 8 2 7 3 4
#> [1] 1 2 8 9 8 2 7 3 4
digits(128, base = 8) # 2 0 0
#> [1] 2 0 0
## one way of pretty printing (base <= 10!)
b2ch <- function(db)
noquote(gsub("^0+(.{1,})$"," \\1",
apply(db, 2, paste, collapse = "")))
b2ch(digitsBase(0:33, 2)) #-> 0 1 10 11 100 101 ... 100001
#> [1] 0 1 10 11 100 101 110 111 1000 1001
#> [11] 1010 1011 1100 1101 1110 1111 10000 10001 10010 10011
#> [21] 10100 10101 10110 10111 11000 11001 11010 11011 11100 11101
#> [31] 11110 11111 100000 100001
b2ch(digitsBase(0:33, 4)) #-> 0 1 2 3 10 11 12 13 20 ... 200 201
#> [1] 0 1 2 3 10 11 12 13 20 21 22 23 30 31 32 33 100 101 102
#> [20] 103 110 111 112 113 120 121 122 123 130 131 132 133 200 201
## Hexadecimal:
i <- c(1:20, 100:106)
M <- digitsBase(i, 16)
hexdig <- c(0:9, LETTERS[1:6])
cM <- hexdig[1 + M]; dim(cM) <- dim(M)
b2ch(cM) #-> 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 ... 6A
#> [1] 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 64 65 66 67 68
#> [26] 69 6A
## IP (Internet Protocol) numbers coding: <n>.<n>.<n>.<n> <--> longinteger
ip_ntoa <- function(n)
apply(digitsBase(n, base = 256), 2, paste, collapse=".")
ip_ntoa(2130706430 + (0:9))# "126.255.255.254" ... "127.0.0.7"
#> [1] "126.255.255.254" "126.255.255.255" "127.0.0.0" "127.0.0.1"
#> [5] "127.0.0.2" "127.0.0.3" "127.0.0.4" "127.0.0.5"
#> [9] "127.0.0.6" "127.0.0.7"
## and the inverse:
ip_aton <- function(a)
bi2int(lapply(strsplit(a, ".", fixed=TRUE), as.integer), 256)
n <- 2130706430 + (0:9)
head(ip <- ip_ntoa(n))
#> [1] "126.255.255.254" "126.255.255.255" "127.0.0.0" "127.0.0.1"
#> [5] "127.0.0.2" "127.0.0.3"
head(ip_aton(ip))
#> [1] 2130706430 2130706431 2130706432 2130706433 2130706434 2130706435
stopifnot( n == ip_aton(ip_ntoa(n )),
ip == ip_ntoa(ip_aton(ip)))
## Inverse of digitsBase() : as.integer method for the "basedInt" class
as.integer(M)
#> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#> 21 22 23 24 25 26 27
#> 100 101 102 103 104 105 106
## or also as.intBase() working from strings:
(cb <- apply(digitsBase(0:33, 4), 2, paste, collapse = ""))
#> [1] "000" "001" "002" "003" "010" "011" "012" "013" "020" "021" "022" "023"
#> [13] "030" "031" "032" "033" "100" "101" "102" "103" "110" "111" "112" "113"
#> [25] "120" "121" "122" "123" "130" "131" "132" "133" "200" "201"
##-> "000" "001" ..... "200" "201"
all(0:33 == as.intBase(cb, base = 4))
#> [1] TRUE