Function hex2integer

If you like a challenge, you can try to write your own function that does the same as what the hex2integer does: convert a 7-nibble long hexadecimal number into a 28 bit signed integer using the information given in tutorial 7. To do this, you may need to do several steps (but if you do it differently/faster, please do so :-):

  • in two’s complement bit notation: when the leading (i.e. the first) bit is 1, than the number is negative, else positive;
  • if the number is negative, then first a bit-inverse should be applied: changing each 0 into a 1, and each 1 into a 0, consider using the str_replace_all function for this;
  • for a negative value, the value is (after the bit-inverse) equal to -(value + 1)
  • the function strtoi can be used to convert data to integers, e.g. from hex to integer use strtoi(x, base = 16L), and from binary to integer usestrtoi(x, base = 2L)`;
  • to convert from from integer to binary, you can use R.utils::intToBin();
  • to check the length of a character string (e.g. a string with binary data, bits), you can use the function str_length;
  • to pad a character string with extra characters (e.g. 0 or 1) before or after the string, use str_pad;

For more background information, see the Wikipedia page on integers in computer science. Check this website for conversions between various representations of numbers, and read more on two’s complement integers here.

Extra challenge
Write your own function, called myHex2IntFun, which converts a hexadecimal representation of longitude or latitude into a numeric coordinate, using the information in tutorial 7 and shown above (and any other piece of information that may be useful).

myHex2IntFun <- function(x) {
  # Get leading hex 'nibble' (thus the 3rd in the character string, the first 2 are prefix 0x)
  leadingHex <- str_sub(x, 3, 3)
  
  # Check whether it corresponds to a negative value
  negativeValue <- leadingHex %in% c("8","9","a","b","c","d","e","f") #  > 8: leading bit = 1 : negative
  
  # Convert the hex to unsigned-integer
  x_int <- strtoi(x, base = 16L)
  
  # Convert to binary format
  x_bin <- R.utils::intToBin(x_int)
  
  # Check number of characters
  nchar(x_bin) # should be 32, but is not
  
  # Pad the bits with 0s or 1s (depending on negativeValue)      
  if(negativeValue) {
    # Pad with ones
    x_bin <- str_pad(x_bin, width = 32L, side = "left", pad = "1")
  }else {
    # Pad with zeros
    x_bin <- str_pad(x_bin, width = 32L, side = "left", pad = "0")
  }
  
  # IF negative: apply bit-inverse
  if(negativeValue) {
    # Bit inverse
    x_bin <- str_replace_all(x_bin, pattern = "1", replacement = "2")
    x_bin <- str_replace_all(x_bin, pattern = "0", replacement = "1")
    x_bin <- str_replace_all(x_bin, pattern = "2", replacement = "0")
  }
  
  # Check length of character vector
  nchar(x_bin) # now indeed 32 bits
  
  # Convert from binary to decimal integer
  y <- strtoi(x_bin, base = 2L)
  
  # IF negative: transform value
  if(negativeValue) {
    y <- -y + 1L
  }
  
  # return
  return(y)
}

Testing the function

To test the function: check whether the input “0x02f979a” return the value 3119002, and the input “0xfdb4cfb’ should return the value -2405123.

myHex2IntFun("0x02f979a")
## [1] 3119002
myHex2IntFun("0xfdb4cfb")
## [1] -2405123

If so, congratulations! You are a coding master!