Search code examples
rubybinarybit-manipulationbitwise-operatorsinteger-overflow

How to left rotate bits of an Integer


I need to left-rotate 32 bits of an Integer by n in Ruby. I'm trying with the canonical implementation:

class Integer
    def rotl32 n
        return (self << n) | (self >> (32 - n))
    end
end

Something is going wrong using large numbers: the result overflows 32 bits. I guess it happened because the theoretical unlimited size of an Integer in Ruby.

How can it be done without overflowing?


Solution

  • Ruby will automatically switch to a different internal representation in order to accommodate larger numbers, so you'll need to cap it with masking:

    class Integer
      def rotl32(n)
        mask = (1 << (32 - n)) - 1
    
        ((self & mask) << n) | (self >> (32 - n))
      end
    end
    

    Where mask indicates which bits should be shifted left, the rest effectively trimmed off before shifting.

    Ruby will gladly do really ridiculous stuff like 1 << (1 << 16) which produces a number 19,729 digits long. This is also an Integer.

    Note if you need this method more performant you'd want to use a look-up table rather than computing every time, though as always I'd benchmark to make sure that approach is faster.