2016-08-10 54 views
2

我在R的工作。我需要找到一个快速的功能,将掩盖整数的最高设置位。例如:屏蔽R中最高位的位?

# 6 binary is 110, this should turn into 010 which is 2 
function_mask(6) = 2 

# 8 in binary is 1000, this should turn into 0000 
function_mask(8) = 0 

这相当于减去两个最接近的较低幂。如果我能找到一个能够找到最接近的两个较低幂的快速函数,我会很高兴。例如:

# 6 in binary is 110, the MSB is 100 
function_power_two(6) = 4 
function_mask(6) = 6 - function_power_two(6) = 2 

# 8 in binary is 1000, the MSB is 1000 which is 8 in base 10 
function_power_two(8) = 8 
function_mask(8) = 8 - function_power_two(8) = 0 

我在R中发现了按位运算:例如bitwShiftL和bitwShiftR。但是,我不知道如何在R中实现解决方案。

我已经看到其他语言的解决方案:JavaCC++。但是,我不知道如何在R中实现这些解决方案。

在C++中有使用Rcpp的解决方案,但是Rcpp不支持大于32位的整数。我需要比那更大的整数。

回答

1

此功能比01更快(4倍)。

pow2 <- c(0,1,2,4,8,16,32,64,128,256,512,1024) 
function_mask <- function(x) x - pow2[findInterval(x, pow2)] 

可以使POW2载体,只要需要,以应对更大的整数

0

有关R解决方案:

function_mask <- function(x) { 
    xb <-intToBits(x) 
    highestbit <- length(xb) - match("01", rev(xb)) 
    x-2L^highestbit 
} 

相比速度其他的答案中,我们看到这个人是最快的,到目前为止。

function_mask1 <- function(x) { 
    bits = intToBits(x)     # Convert integer to binary vector 
    ii = tail(which(bits > 0), n=1)  # Identify most significant bit 
    bits[ii] = as.raw(0)    # Mask the most significant bit 
    out = packBits(bits,type='integer') # Convert binary back to integer 
    return(out) 
} 

maskHighBit <- function(x){ 
    strtoi(gsub("^1", "", R.utils::intToBin(as.integer(x))), base=2)} 

library(microbenchmark) 
microbenchmark(function_mask(112L), function_mask1(112L), maskHighBit(112L), times=1000) 
#Unit: microseconds 
#expr  min  lq  mean median  uq  max neval cld 
#function_mask(112L) 17.961 20.014 23.65080 23.092 24.632 57.475 1000 a 
#function_mask1(112L) 39.514 44.132 49.79744 47.724 49.777 107.765 1000 b 
#maskHighBit(112L) 108.791 114.435 127.53792 118.540 133.422 2054.189 1000 c 
1

你可以做这样的事情:

function_mask <- function(x) { 
    bits = intToBits(x)     # Convert integer to binary vector 
    ii = tail(which(bits > 0), n=1)  # Identify most significant bit 
    bits[ii] = as.raw(0)    # Mask the most significant bit 
    out = packBits(bits,type='integer') # Convert binary back to integer 
    return(out) 
} 

测试:

function_mask(6) = 2 
function_mask(8) = 0 
1

不知道它的速度快,但这里的另一种可能性:

maskHighBit <- function(x){strtoi(sub("^1", "", R.utils::intToBin(x)), base=2)}