From integer to bits and back again

Viewed 95

I'm trying to convert an integer value to its bit expression and convert parts of that again to integer (as per this blogpost, for context).

Transforming integers to bits does seem to work, but I'm missing something when transforming the values back into the initial integer.

'intToBase2' <- function(x){
  x %>% 
    intToBits() %>%
    rev %>%
    as.character() %>%
    {sapply(strsplit(., "", fixed = TRUE), '[', 2)} %>%
    paste0(.,collapse = '')
}
val <- 1855928457
intToBase2(val) # does seem to return the correct bit expression, as expected

However, if I try to reverse the same logic, something gets lost somewhere:

val %>%
  intToBase2 %>%               # Get expression in bits
  {strsplit(.,'')[[1]]} %>%    # split
  sprintf('0%s',.) %>%         # add leading zeros
  rev %>%                      # reverse order
  as.raw %>%                   # expression to raw
  readBin(.,what='integer')

R> [1] 16777217

What am I missing? I assume some of the steps I did are incorrect.

1 Answers

This function reverses yours, and is vectorized:

base2ToInt <- function(string)
{
  sapply(strsplit(string, ""), function(x) sum(rev(+(x == "1")) * 2^(seq(x)-1)))
}

So you can do

base2ToInt(c("1", "0", "10", "11111111"))
#> [1]   1   0   2 255

and

base2ToInt(intToBase2(val))
#> [1] 1855928457
> base2ToInt(intToBase2(val)) == val
#> [1] TRUE

It works by splitting the string(s) into characters, so each string becomes a vector of "1"s and "0"s. These are converted to numeric values, then reversed, then multiplied by a sequence of powers of 2 of the same length. This is summed to give an answer for each string.

It's a bit "code golf", but bit manipulation often is...

Related