在Ruby中将十六进制字符串转换为带符号整数

7
如何在Ruby中将十六进制字符串转换为其32位有符号整数等价物?例如:
a = "fb6d8cf1" #hex string
[a].pack('H*').unpack('l') #from the documentation it unpacks to its 32 bit signed int

它转换成:
-242455045

但实际答案是:
-76706575 

你能指出我哪里做错了吗?

3个回答

4

看起来您遇到了字节序问题。以下代码可以得到您期望的结果:

[a].pack("H*").unpack("l>")
# => [-76706575]
["038a67f90"].pack("H*").unpack("l>")
#=> [59402233]

你用的是哪个版本的Ruby?因为即使使用了L>,我仍然得到-242455045。 - Pavan K
ruby 1.9.3p125(2012-02-16修订版34643)[x86_64-darwin11.3.0] - Michael Kohl
文档中明确指出,l>仅适用于1.9.3及以上版本。不幸的是,我无法在生产服务器上升级Ruby,因此必须找到解决方法。 - Pavan K
你的原始问题没有指定 Ruby 版本,所以我使用了我手头上的版本。 - Michael Kohl

3

您可以翻转字节以解决大小端和符号问题:

>> ['fb6d8cf1'.scan(/[0-9a-f]{2}/i).reverse.join].pack('H*').unpack('l')
=> [-76706575]

0

使用:

class String
  def to_si(base, lenght = 32)
    mid = 2**(length-1)
    max_unsigned = 2**length
    n = self.to_i base
    (n>=mid) ? n - max_unsigned : n
  end
end

"fb6d8cf1".to_si 16, 32

代码适用于负数。谢谢。但是对于正数,例如“038a67f90”,它会失败,因为它被渲染为950435728,而实际值是59402233。 - Pavan K

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