How to solve this example in Ruby
Do rotating left shift and print the value.
- Example with x = 0x12345678
- n = 4 → 0x23456781
- n = 20 → 0x67812345
- n = 2 → 0x048D159E
- rotate_left(unsigned int x, unsigned char n) ...
How to solve this example in Ruby
Do rotating left shift and print the value.
This will perform the wrap-around shift by converting the number to a binary string. Disclaimer: it's horribly inefficient.
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"
It wasn't easy to understand what you wanted to achieve.
A naive approach is to convert the number to a binary string, pad it to 32 length, rotate it and convert it back to a number :
def rotate_left(x, n)
x.to_s(2).rjust(32, '0').each_char.to_a.rotate(n).join.to_i(2)
end
A much more efficient alternative is to apply bitwise operations only:
x
by n
& 0xFFFFFFFF
x
by 32 - n
def rotate_left(x, n)
((x << n) & (2**32 - 1)) | (x >> (32 - n))
end
For both methods:
[4, 20, 2].each do |l|
p rotate_left(0x12345678, l).to_s(16)
end
# "23456781"
# "67812345"
# "48d159e0"
Note that the last output is "48d159e0"
and not "48d159e"
. Without more information, it's hard to know if it's the desired result.