如何将整数转换为二进制向量?

30
如何在R中将整数转换为二进制向量?
例如:
number <- 11
[1] 1 0 1 1

如果我需要将整个数字向量(最小值=0,最大值=300)转换为二进制矩阵,使用R代码或一些现有包中的函数,最快的转换方法是什么?

跟随兔子:base::intToBits

11个回答

34

有一个 intToBits 函数,可以将任何整数转换为长度为 32 的向量,因此您可以执行以下操作:

decimals <- c(3,5,11,4)
m <- sapply(decimals,function(x){ as.integer(intToBits(x))})
m

> m
      [,1] [,2] [,3] [,4]
 [1,]    1    1    1    0
 [2,]    1    0    1    0
 [3,]    0    1    0    1
 [4,]    0    0    1    0
 [5,]    0    0    0    0
 [6,]    0    0    0    0
 [7,]    0    0    0    0
 [8,]    0    0    0    0
 [9,]    0    0    0    0
[10,]    0    0    0    0
[11,]    0    0    0    0
[12,]    0    0    0    0
[13,]    0    0    0    0
[14,]    0    0    0    0
[15,]    0    0    0    0
[16,]    0    0    0    0
[17,]    0    0    0    0
[18,]    0    0    0    0
[19,]    0    0    0    0
[20,]    0    0    0    0
[21,]    0    0    0    0
[22,]    0    0    0    0
[23,]    0    0    0    0
[24,]    0    0    0    0
[25,]    0    0    0    0
[26,]    0    0    0    0
[27,]    0    0    0    0
[28,]    0    0    0    0
[29,]    0    0    0    0
[30,]    0    0    0    0
[31,]    0    0    0    0
[32,]    0    0    0    0

第三行不应该是1011吗? - nikpod
@nikpod,您想要第三列的反转,即0000...00001011 - digEmAll
我的错,我是按行查看它的。数字5和4在行中也巧合地表示出来了。 - nikpod
sapply(decimals,function(x)as.integer(paste(rev( as.integer(intToBits(x))),collapse=""))) - Onyambu
@Onyambu:问题是关于将int转换为位矩阵; 我的只是一个例子,当然你可以粘贴,子串,反转并对该值进行任何操作。 :) - digEmAll
1
matrix(as.integer(intToBits(decimals)), nrow = 32) 可能会更快,因为它是矢量化的。 - jeanlain

29

这篇SO帖子建议使用intToBits函数进行转换。我定义了number2binary函数,其中包括一个参数noBits来控制返回的位数。默认情况下返回32位。

number2binary = function(number, noBits) {
       binary_vector = rev(as.numeric(intToBits(number)))
       if(missing(noBits)) {
          return(binary_vector)
       } else {
          binary_vector[-(1:(length(binary_vector) - noBits))]
       }
    }

还有一些示例:

> number2binary(11)
 [1] 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 0 1 1
> number2binary(11, 4)
[1] 1 0 1 1

2
我得到length(number2binary(0,32))== 31...? - Fabian Werner

13

尝试使用CRAN软件包"binaryLogic"

library(binaryLogic)

as.binary(11)
[1] 1 0 1 1

as.binary(11, littleEndian=TRUE)
[1] 1 1 0 1

as.binary(42, n=16)
[1] 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0

as.binary(0:2, n=2)
[[1]]
[1] 0 0

[[2]]
[1] 0 1

[[3]]
[1] 1 0

as.binary(0xFF)
[1] 1 1 1 1 1 1 1 1

还有其他选项可用:移位、旋转、格雷码等。


1
binaryLogic已从CRAN中移除。 - Cos
你可以从 https://cran.r-project.org/src/contrib/Archive/binaryLogic/(或者在 github 上的 https://github.com/d4ndo/binaryLogic)下载存档的 R 代码,但我个人拒绝使用 devtools,所以不会从那里安装。 - Dalton Bentley

9
您可以使用以下基于 intToBit 的函数来实现此功能:
intToBitVect <- function(x){
  tmp <- rev(as.integer(intToBits(x)))
  id <- seq_len(match(1,tmp,length(tmp))-1)
  tmp[-id]
}

第一行将intToBits的输出转换为数字0和1,并按顺序排列。第二行检查需要保留哪些值,如下所示:
  • 使用match检查第一个1出现的位置。如果找不到1,则要求match返回tmp向量的长度。
  • 使用seq_len从1到第一个出现1的位置之前创建一个序列。
  • 删除所有这些位置在tmp向量中的位置。
为了展示它是如何工作的:
> intToBitVect(11)
[1] 1 0 1 1
> intToBitVect(0)
[1] 0

7
我在M.J. Crawley的"The R Book"中找到了一个解决方案,即下面的函数:
binary <- function(x) {
  i <- 0
  string <- numeric(32)
  while(x > 0) {
    string[32 - i] <- x %% 2
    x <- x %/% 2
    i <- i + 1 
  }
  first <- match(1, string)
  string[first:32] 
}

4

And another:

toBits <- function (x, nBits = 8){
   tail(rev(as.numeric(intToBits(x))),nBits)
}

3
intToBin <- function(x){
  if (x == 1)
    1
  else if (x == 0)
    NULL
  else {
   mod <- x %% 2
   c(intToBin((x-mod) %/% 2), mod)
  }
}

所以intToBin(10)返回
[1] "1" "0" "1" "0"

如果您需要字符串而非向量

> paste0(intToBin(10), collapse = "")
[1] "1010"

2
如果你想返回一个二进制序列,即由1和0构成的向量,则此函数可以为您完成此操作,但它只能一次处理一个数字。请保留HTML标记。
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)
}

2
你实际上不需要调用任何函数来获得答案 - 只需使用模运算即可。
int_to_binary <- function(num, pow) {
  if(2^(pow + 1) - 1 < num) stop("Use a higher values of 'pow'")
  num %/% (2^(pow:0)) %% 2
}

1

这里是一个Rcpp的实现。

在Rstudio中,将以下代码保存在文件中,例如binary.cpp,然后输入Source

//************************
// binary.cpp 
#include <RcppArmadillo.h>

//' @Title get the binary representation of a positive integer
// [[Rcpp::depends(RcppArmadillo)]]
//[[Rcpp::export]]
void intToBinary(int n, arma::vec& a ) {
  for(int i=0;n>0;i++){
    a[i]=n%2;
    n=n/2;
  }
}
//************************

如果 Source 进行顺利,从 R 控制台中输入以下内容:
> a <- rep(0,10) # needed to store the binary representation
> myInt <- 5 # to be converted to binary form
> intToBinary(myInt, a)
> rev(a) # print in the usual form

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接