我在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
这相当于减去最接近的2的较低功率。如果我能找到一个能够找到最接近的2的较低功率的快速功能,我将很高兴。例如:
# 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中实现解决方案。
我见过其他语言的解决方案:Java,C和C++。但是,我不知道如何在R中实现这些解决方案。
C ++中有使用Rcpp的解决方案,但Rcpp不支持大于32位的整数。我需要更大的整数。
答案 0 :(得分: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 :(得分:1)
不确定它是否快速,但这是另一种可能性:
maskHighBit <- function(x){strtoi(sub("^1", "", R.utils::intToBin(x)), base=2)}
答案 2 :(得分:1)
此功能比the answer I posted earlier更快(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矢量,以应对更大的整数
答案 3 :(得分: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