在R中将十六进制转换为十进制

33

我发现在fBasics包中有一个名为.hex.to.dec的函数。

当我使用.hex.to.dec(a)时,它能够正常工作。

我有一个数据框,其中一列名为samp_column,包含这样的值:

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

当我使用.hex.to.dec(samp_column)时,我遇到了以下错误:

"Error in nchar(b) : 'nchar()'需要一个字符向量"

当我使用.hex.to.dec(as.character(samp_column))时,我遇到了以下错误:

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

请问有什么最好的解决方法吗?


3
strtoi 可以完成这个任务。或者用较长的方式:Rutils::as.character.binmode,然后使用 as.numeric 将字符转换为数字 :-) - Carl Witthoft
谢谢你,Carl!不知道为什么这个函数在我的谷歌搜索结果中没有出现,但它看起来非常有效。:) 干杯! - albay_aureliano
5个回答

47

使用base::strtoi将十六进制字符向量转换为整数:

strtoi(c("0xff", "077", "123"))
#[1] 255  63 123

9
在数字进制转换中,寻找正确的帮助页面可能会很困难。转换函数散布在各个地方,且名称各不相同。另请参阅?hexmode?as.hexmode?octmode - IRTFM
好的,现在谁在发布短回答?:-)。附言:感谢对弹球的赞美。 - Carl Witthoft
@CarlWitthoft 哈!好的,我明白了。我更倾向于把这个看作是一个最小可行示例,但正如你所说,这是一条微妙的界线,像弹球大师一样。 :-) - Simon O'Hanlon
3
由于某些原因,当我尝试跟随你的示例并尝试strtoi(c('a','b','c','d','e','f'))时,我得到的结果是NA。但是你的示例可以正常工作。我在这里错过了什么?编辑:好的,我需要在每个十六进制数之前添加0x - dasf
1
@dasf 你需要指定基数 strtoi(c('a','b','c','d','e','f'), 16) 应该返回一个答案。 - Onyambu

15

使用"C/C++方式",有一种简单通用的方法可以将十六进制与其他格式相互转换:

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"

14

@user4221472的回答中所提到的,strtoi()在大于2^31的整数上会发生溢出。

绕过这个问题最简单的方法是使用as.numeric()

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

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

正如评论中@MS Berends所指出的那样,"还要注意,在控制台中仅打印V就已经以十进制打印了。"


不错...你可以补充一下,如果不喜欢科学计数法,可以设置options(digits = 22) - loki
1
只是评论一下,指出这个方法非常有用,可以绕过strtoi在31位限制的限制。 - Rafa
1
还要注意的是,仅在控制台中打印“V”就已经以十进制打印了。 - MS Berends

8

strtoi() 的限制是 31 位。高阶位设置的十六进制数返回 NA

> strtoi('0x7f8cff8b')
[1] 2139946891
> strtoi('0x8f8cff8b')
[1] NA

0

要获取一个带有16位的有符号值:

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

一般形式如下:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接