从二进制文件读取整数<;R中的8位
在R中,我试图将二进制数据转换为整数值,但不是将1个值存储在1个字节中,而是将多个值存储在字节内或跨字节存储 我知道有12个整数值存储在64位(8字节)上。12个整数的位计数如下:5,6,5,5,4,7,5,6,5,5,4,7 在以下代码之后:从二进制文件读取整数<;R中的8位,r,binary-data,R,Binary Data,在R中,我试图将二进制数据转换为整数值,但不是将1个值存储在1个字节中,而是将多个值存储在字节内或跨字节存储 我知道有12个整数值存储在64位(8字节)上。12个整数的位计数如下:5,6,5,5,4,7,5,6,5,5,4,7 在以下代码之后: time我不知道用标准的数据库函数(像redBin这样的函数似乎更喜欢一次不少于一个字节)有什么简洁优雅的方法来实现这一点。所以我创建了一个函数,它可以进行一些复杂的计算,从字节中提取位并将它们转换成数字。最后,我确实在base R中使用了按位运算符(请
time我不知道用标准的数据库函数(像redBin
这样的函数似乎更喜欢一次不少于一个字节)有什么简洁优雅的方法来实现这一点。所以我创建了一个函数,它可以进行一些复杂的计算,从字节中提取位并将它们转换成数字。最后,我确实在base R中使用了按位运算符(请参见?bitwAnd
)
bitints <- function(bytes, bitlengths) {
stopifnot(sum(bitlengths) <= 8*length(bytes))
stopifnot(all(bitlengths <= 8))
bytebits <- rep.int(8, length(bytes))
masks <- c(1L,3L,7L,15L,31L,63L,127L, 255L)
outs <- numeric(length(bitlengths))
for(i in seq_along(bitlengths)) {
need <- bitlengths[i]
got <- 0
r <- 0
while(need>0) {
j <- which(bytebits>0)[1]
bitget <- min(need, bytebits[j])
r <- r + bitwShiftL(bitwAnd(bytes[j],masks[bitget]), got)
bytebits[j] = bytebits[j]-bitget
bytes[j] = bitwShiftR(bytes[j], bitget)
need <- need - bitget
got <- got + bitget
}
outs[i] <- r
}
outs
}
bit注意,对每个4字节整数的操作是相同的(模式重复两次)。因此,解决4字节整数的问题,并循环文件中的4字节整数(通过readBin
)进行循环就足够了。这比逐字节考虑问题要简单得多
# length(x) should be 1
bitint <- function(x, bitlens) {
result <- integer(length(bitlens))
for (i in seq_along(bitlens)) {
result[i] <- bitwAnd(x, (2^bitlens[i])-1)
x <- bitwShiftR(x, bitlens[i])
}
return(result)
}
bitlens <- c(5,6,5,5,4,7)
x <- c(1064410137L, 1064410838L)
c(sapply(x, function(i) bitint(i, bitlens)))
## [1] 25 32 19 17 11 31 22 54 19 17 11 31
#长度(x)应为1
如果第二个值只占5位,它怎么可能是32位?捕捉得好(其中两个数字的顺序错误)。位计数现在是正确的。这非常有效。提取4字节整数是个好主意。非常感谢。
# length(x) should be 1
bitint <- function(x, bitlens) {
result <- integer(length(bitlens))
for (i in seq_along(bitlens)) {
result[i] <- bitwAnd(x, (2^bitlens[i])-1)
x <- bitwShiftR(x, bitlens[i])
}
return(result)
}
bitlens <- c(5,6,5,5,4,7)
x <- c(1064410137L, 1064410838L)
c(sapply(x, function(i) bitint(i, bitlens)))
## [1] 25 32 19 17 11 31 22 54 19 17 11 31