如何转换Ruby字节"放n"

时间:2017-04-21 14:00:09

标签: ruby byte

如何在Ruby中解决这个例子

旋转左移并打印值。

  • x = 0x12345678
  • 的示例
  • n = 4→0x23456781
  • n = 20→0x67812345
  • n = 2→0x048D159E
  • rotate_left(unsigned int x,unsigned char n) ...

2 个答案:

答案 0 :(得分:2)

这将通过将数字转换为二进制字符串来执行环绕移位。免责声明:它非常低效。

def rotate_left x, n
  b = x.to_s(2).rjust(32, '0')
  "#{b[n...b.length]}#{b[0...n]}".to_i(2)
end

# >  "0x" + rotate_left(0x12345678), 4).to_s(16)
# => "0x23456781"
#
# >  "0x" + rotate_left(0x12345678), 20).to_s(16)
# => "0x67812345"
#
# >  "0x" + rotate_left(0x12345678), 20).to_s(16)
# => "0x48d159e0"

答案 1 :(得分:1)

要理解你想要达到的目标并不容易。

一种天真的方法是将数字转换为二进制字符串,将其填充为32长度rotate it并将其转换回数字:

def rotate_left(x, n)
  x.to_s(2).rjust(32, '0').each_char.to_a.rotate(n).join.to_i(2)
end

更有效的替代方法是仅应用bitwise operations

  • x左移n
    • 如果它大于2 ** 32-1,则用& 0xFFFFFFFF
    • 截断它
  • x
  • 右移32 - n
  • 在这两个数字之间按位OR应用
def rotate_left(x, n)
  ((x << n) & (2**32 - 1)) | (x >> (32 - n))
end

对于这两种方法:

[4, 20, 2].each do |l|
  p rotate_left(0x12345678, l).to_s(16)
end
# "23456781"
# "67812345"
# "48d159e0"

请注意,最后一个输出是"48d159e0"而不是"48d159e"。没有更多信息,很难知道它是否是理想的结果。