Search code examples
rubybinaryxor

Ruby Convert integer to binary to integer array of set bits


Lets say I have an integer 98. The binary representation of this string would be:

(98).to_s(2) # 1100010

Now I want to convert this binary string to an integer array of all the bits that are set. This would give me:

[64,32,2]

How would I go about this?

Update: The conversion of int to int array does not necessarily need to involve String, it is just what I knew. I assume non String operations would also be faster.

Ruby is amazing seeing all these different ways to handle this!


Solution

  • This would work:

    i = 98
    (0...i.bit_length).map { |n| i[n] << n }.reject(&:zero?)
    #=> [2, 32, 64]
    
    • Fixnum#bit_length returns the position of the highest "1" bit
    • Fixnum#[n] returns the integer's nth bit, i.e. 0 or 1
    • Fixnum#<< shifts the bit to the left. 1 << n is equivalent to 2n

    Step by step:

    (0...i.bit_length).map { |n| i[n] }
    #=> [0, 1, 0, 0, 0, 1, 1]
    
    (0...i.bit_length).map { |n| i[n] << n }
    #=> [0, 2, 0, 0, 0, 32, 64]
    
    (0...i.bit_length).map { |n| i[n] << n }.reject(&:zero?)
    #=> [2, 32, 64]
    

    You might want to reverse the result.

    In newer versions of Ruby (2.7+) you could also utilize filter_map and nonzero? to remove all 0 values:

    (0...i.bit_length).filter_map { |n| (i[n] << n).nonzero? }
    #=> [2, 32, 64]