Daniel Schierbeck
8/7/2006 3:56:00 PM
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