在R中将十进制转换为二进制?

Jay*_*Jay 35 r

"0000000000000101"在R 中将数字转换为基数2(在字符串中,例如5将被转换为)的最简单方法是什么?有intToBits,但它返回一个字符串向量而不是字符串:

> intToBits(12)
 [1] 00 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[26] 00 00 00 00 00 00 00
Run Code Online (Sandbox Code Playgroud)

我尝试了其他一些功能,但没有成功:

> toString(intToBits(12))
[1] "00, 00, 01, 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00"
Run Code Online (Sandbox Code Playgroud)

nic*_*ico 25

paste(rev(as.integer(intToBits(12))), collapse="") 做的工作

paste使用collapse参数将向量折叠为字符串.您必须使用rev获取正确的字节顺序.

as.integer 删除多余的零


Jos*_*ich 19

请注意,intToBits()返回"原始"向量,而不是字符向量(字符串).请注意,我的回答是@ nico原始答案的略微扩展,从每个位中删除前导"0":

paste(sapply(strsplit(paste(rev(intToBits(12))),""),`[[`,2),collapse="")
[1] "00000000000000000000000000001100"
Run Code Online (Sandbox Code Playgroud)

为了清楚起见,要打破这些步骤:

# bit pattern for the 32-bit integer '12'
x <- intToBits(12)
# reverse so smallest bit is first (little endian)
x <- rev(x)
# convert to character
x <- as.character(x)
# Extract only the second element (remove leading "0" from each bit)
x <- sapply(strsplit(x, "", fixed = TRUE), `[`, 2)
# Concatenate all bits into one string
x <- paste(x, collapse = "")
x
# [1] "00000000000000000000000000001100"
Run Code Online (Sandbox Code Playgroud)

或者,正如@nico所示,我们可以使用as.integer()更简洁的方法从每个位中删除前导零.

x <- rev(intToBits(12))
x <- paste(as.integer(x), collapse = "")
# [1] "00000000000000000000000000001100"
Run Code Online (Sandbox Code Playgroud)

只是为了方便复制粘贴,这里是上面的功能版本:

dec2bin <- function(x) paste(as.integer(rev(intToBits(x))), collapse = "")
Run Code Online (Sandbox Code Playgroud)


小智 17

我认为您可以使用R.utils包,然后使用intToBin()函数

>library(R.utils)

>intToBin(12)
[1] "1100"

> typeof(intToBin(12))
[1] "character"
Run Code Online (Sandbox Code Playgroud)


ins*_*ven 9

intToBits限制为最大2 ^ 32,但如果我们想将1e10转换为二进制怎么办?这是将浮点数转换为二进制的函数,假设它们是存储为的大整数numeric.

dec2bin <- function(fnum) {
  bin_vect <- rep(0, 1 + floor(log(fnum, 2)))
  while (fnum >= 2) {
    pow <- floor(log(fnum, 2))
    bin_vect[1 + pow] <- 1
    fnum <- fnum - 2^pow
  } # while
  bin_vect[1] <- fnum %% 2
  paste(rev(bin_vect), collapse = "")
} #dec2bin
Run Code Online (Sandbox Code Playgroud)

此函数在2 ^ 53 = 9.007199e15之后开始松散数字,但适用于较小的数字.

microbenchmark(dec2bin(1e10+111))
# Unit: microseconds
#                 expr     min       lq     mean   median      uq    max neval
# dec2bin(1e+10 + 111) 123.417 125.2335 129.0902 126.0415 126.893 285.64   100
dec2bin(9e15)
# [1] "11111111110010111001111001010111110101000000000000000"
dec2bin(9e15 + 1)
# [1] "11111111110010111001111001010111110101000000000000001"
dec2bin(9.1e15 + 1)
# [1] "100000010101000110011011011011011101001100000000000000"
Run Code Online (Sandbox Code Playgroud)

  • 我遇到了一个问题,我需要使用大数字操作,并在stackoverflow上搜索解决方案后最终编写了我自己的代码:) (2认同)

小智 6

看看R.utils包 - 你有一个名为intToBin的函数...

http://rss.acs.unt.edu/Rdoc/library/R.utils/html/intToBin.html


Ram*_*les 5

此函数将取一个十进制数并返回相应的二进制序列,即 1 和 0 的向量

dectobin <- function(y) {
  # find the binary sequence corresponding to the decimal number 'y'
  stopifnot(length(y) == 1, mode(y) == 'numeric')
  q1 <- (y / 2) %/% 1
  r <- y - q1 * 2
  res = c(r)
  while (q1 >= 1) {
    q2 <- (q1 / 2) %/% 1
    r <- q1 - q2 * 2
    q1 <- q2
    res = c(r, res)
  }
  return(res)
}
Run Code Online (Sandbox Code Playgroud)


rus*_*rce 5

哦,但是,如果您有一个由bit64软件包启用的64位整数,该怎么办?除了@epwalsh的答案外,给出的每个答案都不会在64位整数上运行,因为R和R.utils的基于C的内部不支持它。@epwalsh的解决方案很棒,并且如果您先加载bit64程序包,则可以在R中工作,除非R中的它(使用循环)速度慢(所有速度都是相对的)。

o.dectobin <- function(y) {
  # find the binary sequence corresponding to the decimal number 'y'
  stopifnot(length(y) == 1, mode(y) == 'numeric')
  q1 <- (y / 2) %/% 1
  r <- y - q1 * 2
  res = c(r)
  while (q1 >= 1) {
    q2 <- (q1 / 2) %/% 1
    r <- q1 - q2 * 2
    q1 <- q2
    res = c(r, res)
  }
  return(res)
}

dat <- sort(sample(0:.Machine$integer.max,1000000))
system.time({sapply(dat,o.dectobin)})
#   user  system elapsed 
# 61.255   0.076  61.256 
Run Code Online (Sandbox Code Playgroud)

如果我们字节编译它,我们可以做得更好。

library(compiler)
c.dectobin <- cmpfun(o.dectobin)
system.time({sapply(dat,c.dectobin)})
#   user  system elapsed 
# 38.260   0.010  38.222 
Run Code Online (Sandbox Code Playgroud)

...但是仍然很慢。如果我们使用C编写自己的内部结构,我们的速度将大大提高(这是我在这里所做的工作,是从@epwalsh的代码中借用的-显然我不是C程序员)...

o.dectobin <- function(y) {
  # find the binary sequence corresponding to the decimal number 'y'
  stopifnot(length(y) == 1, mode(y) == 'numeric')
  q1 <- (y / 2) %/% 1
  r <- y - q1 * 2
  res = c(r)
  while (q1 >= 1) {
    q2 <- (q1 / 2) %/% 1
    r <- q1 - q2 * 2
    q1 <- q2
    res = c(r, res)
  }
  return(res)
}

dat <- sort(sample(0:.Machine$integer.max,1000000))
system.time({sapply(dat,o.dectobin)})
#   user  system elapsed 
# 61.255   0.076  61.256 
Run Code Online (Sandbox Code Playgroud)

```

  • ...我现在注意到这是完全荒谬的,因为bit64的as.bitstring函数的速度是我的Rcpp函数的两倍...但是我在这里将其保留为愚蠢的纪念碑,并可能提示如何从integer64到C ++的桥梁,然后再返回……但是,如果您需要一种更有效的方式来做到这一点,肯定可以看到bit64源代码。 (2认同)
  • bit64将`integer64`实现为一个两倍-一个`REALSXP`。一个double是64位,一个64位整数也是。相同的内存量,但是内容的表示方式不同。我的评论归因于此页面上,以解决@MichaelChirico的评论/编辑我的答案。我碰巧读了你的评论,这让我微笑着想到了那个链接。 (2认同)