33

I found out that there is function called .hex.to.dec in the fBasics package.

When I do .hex.to.dec(a), it works.

I have a data frame with a column samp_column consisting of such values:

a373, 115c6, a373, 115c6, 176b3

When I do .hex.to.dec(samp_column), I get this error:

"Error in nchar(b) : 'nchar()' requires a character vector"

When I do .hex.to.dec(as.character(samp_column)), I get this error:

"Error in rep(base.out, 1 + ceiling(log(max(number), base = base.out))) : invalid 'times' argument"

What would be the best way of doing this?

zx8754
  • 52,746
  • 12
  • 114
  • 209
albay_aureliano
  • 417
  • 1
  • 5
  • 11
  • 3
    `strtoi` will do it. Or the long way: `Rutils::as.character.binmode` and then convert from character to number with `as.numeric` :-) – Carl Witthoft Oct 21 '13 at 18:49
  • 3
    Please read about [how to format your question](http://stackoverflow.com/editing-help) and then about [how to make a reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) that includes your data. – Thomas Oct 21 '13 at 18:49
  • Thank you Carl! For some reason, this function did not show up in my Google searches, but it seems to work really well. :) Cheers! – albay_aureliano Oct 21 '13 at 20:31

5 Answers5

47

Use base::strtoi to convert hexadecimal character vectors to integer:

strtoi(c("0xff", "077", "123"))
#[1] 255  63 123
Thomas
  • 43,637
  • 12
  • 109
  • 140
Simon O'Hanlon
  • 58,647
  • 14
  • 142
  • 184
  • 9
    Conversion across numeric bases is one of those tasks where it can be difficult to locate the right help pages. The conversion functions are scattered all over the place with diverse names. See also `?hexmode`, `?as.hexmode`, and `?octmode` – IRTFM Oct 21 '13 at 20:30
  • OK, *now* who's posting short answers? :-). PS thx for the pinball praise . – Carl Witthoft Oct 22 '13 at 11:39
  • @CarlWitthoft ha! Ok, point taken. I prefer to think of this as a minimum workable example, but as you said, it's a fine line pinball wizard. :-) – Simon O'Hanlon Oct 22 '13 at 13:16
  • 3
    For some reason, when I try to follow your example and try `strtoi(c('a','b','c','d','e','f'))`, all I get is NA. But your examples work just fine. What am I missing here? EDIT: OK, I needed to add `0x` before each hex number. – dasf Jun 27 '18 at 10:03
  • 1
    @dasf you need to specify the base `strtoi(c('a','b','c','d','e','f'), 16)` should return an answer – Onyambu Jun 26 '23 at 21:18
15

There is a simple and generic way to convert hex <-> other formats using "C/C++ way":

V <- c(0xa373, 0x115c6, 0xa373, 0x115c6, 0x176b3)

sprintf("%d", V)
#[1] "41843" "71110" "41843" "71110" "95923"

sprintf("%.2f", V)
#[1] "41843.00" "71110.00" "41843.00" "71110.00" "95923.00"

sprintf("%x", V)
#[1] "a373"  "115c6" "a373"  "115c6" "176b3"
tonytonov
  • 25,060
  • 16
  • 82
  • 98
14

As mentioned in @user4221472's answer, strtoi() overflows with integers larger than 2^31.

The simplest way around that is to use as.numeric().

V <- c(0xa373, 0x115c6, 0x176b3, 0x25cf40000)

as.numeric(V)
#[1]       41843       71110       95923 10149429248

As @MS Berends noted in the comments, "[a]lso notice that just printing V in the console will already print in decimal."

Fato39
  • 746
  • 1
  • 11
  • 26
  • Nice... You might add, that you can set `options(digits = 22)` if one does not like scientific notation. – loki Jul 09 '20 at 09:41
  • 1
    Just commenting to remark this has been extremely useful to bypass the mentioned limitation of 31 bits in `strtoi` – Rafa Mar 30 '22 at 03:09
  • 1
    Also notice that just printing `V` in the console will already print in decimal. – MS Berends Jul 31 '22 at 13:10
8

strtoi() has a limitation of 31 bits. Hex numbers with the high order bit set return NA:

> strtoi('0x7f8cff8b')
[1] 2139946891
> strtoi('0x8f8cff8b')
[1] NA
Paolo
  • 3,825
  • 4
  • 25
  • 41
user4221472
  • 81
  • 1
  • 2
0

To get a signed value with 16 bits:

  temp <- strtoi(value, base=16L)
  if (temp>32767){ temp <- -(65535 - temp) }

In a general form:

  max_unsigned <- 65535 #0xFFFF
  max_signed <- 32767 #0x7FFF
  temp <- strtoi(value, base=16L)
  if (temp>max_signed){ temp <- -(max_unsigned- temp) }
Jean Castro
  • 311
  • 2
  • 6