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

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

 > 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 

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

 > 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" 

@尼科的回答略有延伸。 这将从每个位中删除前导“0”:

 paste(sapply(strsplit(paste(rev(intToBits(12))),""),`[[`,2),collapse="") [1] "00000000000000000000000000001100" 

paste(rev(as.integer(intToBits(12))), collapse="")完成这项工作

pastecollapse参数折叠成一个string的向量。 你必须使用rev来获得正确的字节顺序。

as.integer删除多余的零

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

 >library(R.utils) >intToBin(12) [1] "1100" > typeof(intToBin(12)) [1] "character" 

看看R.utils包 – 你有一个叫做intToBin的函数…

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

intToBits被限制为最大2 ^ 32,但是如果我们想要将1e10转换为二进制呢? 这里是将浮点数转换为二进制的函数,假设它们是以numericforms存储的大整数。

 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 

该函数在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" 

这个函数将取一个十进制数并返回相应的二进制序列,即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) } 

哦,但是如果你有一个64位整数由bit64软件包启用怎么办? 除了@epwalsh之外,每个给出的答案都不能在64位整数上运行,因为R和R.utils的C基础内部不支持它。 @ epwalsh的解决scheme是伟大的,并在R中工作,如果你加载bit64包第一,除了(使用循环)在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 

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

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

…但还是很慢 如果我们用C语言编写自己的内部函数(这是我在这里从@ epwalsh的代码中借用的,我不是一个C程序员)

 library(Rcpp) library(inline) library(compiler) intToBin64.worker <- cxxfunction( signature(x = "string") , ' #include <string> #include <iostream> #include <sstream> #include <algorithm> // Convert the string to an integer std::stringstream ssin(as<std::string>(x)); long y; ssin >> y; // Prep output string std::stringstream ssout; // Do some math int64_t q2; int64_t q1 = (y / 2) / 1; int64_t r = y - q1 * 2; ssout << r; while (q1 >= 1) { q2 = (q1 / 2) / 1; r = q1 - q2 * 2; q1 = q2; ssout << r; } // Finalize string //ssout << r; //ssout << q1; std::string str = ssout.str(); std::reverse(str.begin(), str.end()); return wrap(str); ', plugin = "Rcpp" ) system.time(sapply(as.character(dat),intToBin64.worker)) # user system elapsed # 7.166 0.010 7.168 

“`

尝试»二元逻辑«

 library(binaryLogic) ultimate_question_of_life_the_universe_and_everything <- as.binary(42) summary(ultimate_question_of_life_the_universe_and_everything) #> Signedness Endianess value<0 Size[bit] Base10 #> 1 unsigned Big-Endian FALSE 6 42 > as.binary(0:3, n=2) [[1]] [1] 0 0 [[2]] [1] 0 1 [[3]] [1] 1 0 [[4]] [1] 1 1