Rick DeNatale wrote:
> On 8/7/06, Daniel Schierbeck <daniel.schierbeck / gmail.com> wrote:
>> Ch Skilbeck wrote:
>> > def nextPowerOf2(n)
>> >   raise "integer please" if !n.kind_of? Integer
>> >   high = 0
>> >   count = 0
>> >   (0..n.size * 8 - 2).each {|b| count += n[b] ; high = b if n[b] != 0}
>> >   1 << high + (count > 1 ? 1 : 0)
>> > end
>>
>> Your question has already been answered by Simon, but I'd like to show
>> you how your code could be more Rubyesque.
>>
>> First off, method name are always lower_case_with_underscore, so
>>
>>    def next_power_of_2(n)
>>
>> Ruby has the `unless' keyword, so
>>
>>    raise "integer please" unless n.kind_of? Integer
>>
>> but you don't really have to check the argument's class -- just check if
>> the provided object responds to #to_int, or don't even check at all.
>>
>>    raise "integer please" unless n.respond_to? :to_int
>>    n = n.to_int
>>
>> Parallel assignment is cool
>>
>>    high, count = 0, 0
>>
>> I'd split the next part up, but that may just be me
>>
>>    (0..(n.size * 8 - 2)).each do |b|
>>      count += n[b]
>>      high = b unless n[b] == 0
>>    end
>>
>> Just some thoughts
> 
> Here's another take
> 
> irb(main):016:0> class Fixnum
> irb(main):017:1>     def next_power_of_2
> irb(main):018:2>       trial = 1
> irb(main):019:2>       trial <<= 1 while trial < self
> irb(main):020:2>       return trial
> irb(main):021:2>     end
> irb(main):022:1> end
> => nil
> irb(main):023:0> (-1..10).collect { | i | [i, i.next_power_of_2] }
> => [[-1, 1], [0, 1], [1, 1], [2, 2], [3, 4], [4, 4], [5, 8], [6, 8],
> [7, 8], [8, 8], [9, 16], [10, 16]]
> irb(main):024:0>
> 
> This should be fairly fast since at first glance it's o(log2(n))
> 
> And it makes it a method of Fixnum
> 

Very nice. Better add it to Integer instead, though -- otherwise Bignums 
won't have the method.


Cheers,
Daniel