Just to show the speed of the suggested answers:
require 'benchmark' ORIG_NUMBER = 19767 def f(x,i,j) b = x.to_s(2) n = b.size b[(nj-1)...(ni)].to_i(2) end class Fixnum def bit_range low, high len = high - low + 1 self >> low & ~(-1 >> len << len) end def slice(range_or_start, length = nil) if length start = range_or_start else range = range_or_start start = range.begin length = range.count end mask = 2 ** length - 1 self >> start & mask end end def pn puts "0b#{n.to_s(2)}"; n end n = 1_000_000 puts "Using #{ n } loops in Ruby #{ RUBY_VERSION }." Benchmark.bm(21) do |b| b.report('texasbruce') { n.times { ORIG_NUMBER.to_s(2)[(-8 - 1)..(-3 - 1)].to_i(2) } } b.report('DigitalRoss string') { n.times { ORIG_NUMBER.to_s(2)[-9..-4].to_i(2) } } b.report('DigitalRoss binary') { n.times { ORIG_NUMBER >> 3 & 0x3f } } b.report('DigitalRoss bit_range') { n.times { 19767.bit_range(3, 8) } } b.report('Philip') { n.times { f(ORIG_NUMBER, 3, 8) } } b.report('Semyon Perepelitsa') { n.times { ORIG_NUMBER.slice(3..8) } } end
And the conclusion:
Using 1000000 loops in Ruby 1.9.3. user system total real texasbruce 1.240000 0.010000 1.250000 ( 1.243709) DigitalRoss string 1.000000 0.000000 1.000000 ( 1.006843) DigitalRoss binary 0.260000 0.000000 0.260000 ( 0.262319) DigitalRoss bit_range 0.840000 0.000000 0.840000 ( 0.858603) Philip 1.520000 0.000000 1.520000 ( 1.543751) Semyon Perepelitsa 1.150000 0.010000 1.160000 ( 1.155422)
What's on my old MacBook Pro. Your mileage may vary.
source share