Looping through bits in an integer, ruby
bit, integer, loops, ruby
Solution
To determine the length of the longest sequence of consecutive 1's, this is more efficient:
def longest_one_chain(n)
c = 0
while n != 0
n &= n >> 1
c += 1
end
c
end
The method simply counts how many times you can "bitwise AND" the number with itself shifted 1 bit to the right until it is zero.
Example:
______ <-- longest chain
01011011100001111110011110101010 c=0
AND 0101101110000111111001111010101
1001100000111110001110000000 c=1, 1’s deleted
AND 100110000011111000111000000
100000011110000110000000 c=2, 11’s deleted
AND 10000001111000011000000
1110000010000000 c=3, 111’s deleted
AND 111000001000000
110000000000000 c=4, 1111’s deleted
AND 11000000000000
10000000000000 c=5, 11111’s deleted
AND 1000000000000
0 c=6, 111111’s deleted
Problem
I am making a program where one of the problems is that I need to do some analysis of the bit pattern in some integers. Because of this I would like to be able to do something like this: ``` #Does **NOT** work: num.each_bit do |i| #do something with i end ``` I was able to make something that works, by doing: ``` num.to_s(2).each_char do |c| #do something with c as a char end ``` This however does not have the performance I would like. I have found that you can do this: ``` 0.upto(num/2) do |i| #do something with n[i] end ``` This have even worse performance than the `each_char` method This loop is going to be executed millions of times, or more, so I would like it to be as fast as possible. For reference, here is the entirety of the function ``` @@aHashMap = Hash.new(-1) #The method finds the length of the longes continuous chain of ones, minus one #(101110 = 2, 11 = 1, 101010101 = 0, 10111110 = 4) def afunc(n) if @@aHashMap[n] != -1 return @@aHashMap[n] end num = 0 tempnum = 0 prev = false (n.to_s(2)).each_char do |i| if i if prev tempnum += 1 if tempnum > num num = tempnum end else prev = true end else prev = false tempnum = 0 end end @@aHashMap[n] = num return num end ```