Help us understand the problem. What is going on with this article?

Rubyでのビット操作向けGem

More than 3 years have passed since last update.

この前に、popcountを計算するGemを作りましたが、やりたいことが増えてきたのでbit_countという名前も合わなくなるということで、新たなGemにすることにしました。題して、bit_utilsとしています。

3つの機能

名前的には汎用とできるようになったところで、現状の機能は3つを用意しています。ビット単位のAND/ORやシフトについては、通常のRubyの演算でまかなえるので、特段用意はしていません。

popcount

元になったbit_counterの機能を引き継いで、1になっているビットの数を数える機能があります。ただし、前のところでも書いたように、負の数では1のビットが無限個になってしまうので、0の個数を数えてマイナスで返します。

popcount.rb
require 'bit_utils'

p BitUtils.popcount(0) # => 0
p BitUtils.popcount(1) # => 1
p BitUtils.popcount(65535) # => 16

p BitUtils.popcount(-2) # => -1

trailing_zeros

Rubyの整数には「全体幅」という概念が存在しないのですが、その代わりに有意なビット数を返すbit_lengthメソッドがあります。そして、多くのCPUでは固定幅の整数に対して、「上のビットから0が続く数」「下のビットから0が続く数」を数えるような命令があります。

ということで、Rubyでも「下のビットから0が続く数」を知りたくなって作ることにしました。なお、0の時は-1を返すようにしてあります。マイナスの時も特段のハンドリングは必要ないので、適切な値を返します。

trailing_zeros.rb
require 'bit_utils'

p BitUtils.trailing_zeros(0) # => -1
p BitUtils.trailing_zeros(1) # => 0
p BitUtils.trailing_zeros(2) # => 1
p BitUtils.trailing_zeros(1000) # => 3
p BitUtils.trailing_zeros(65536) # => 16

p BitUtils.popcount(-2) # => 1

each_bit

整数をビットの集合として扱うような場合に、その要素ごとに繰り返し実行するようなメソッドです。なお、yieldの順序は不定で、また負の数の時は例外を投げます。

他のeach系メソッドと同様、ブロックを渡さない場合にはEnumeratorを返すので、.to_aなど好きなように使えます。

each_bit.rb
require 'bit_utils'

BitUtils.each_bit(0) { |b| p b } # しかし、なにもおこらなかった!
BitUtils.each_bit(1) { |b| p b } # => 0

BitUtils.each_bit(63).to_a # => 0から7まで入った配列(順番は不定)

コア拡張

require 'bit_utils/core_ext'とすると、Integerに上3つのメソッドが生えます。require 'bit_utils/core_ext/each_bit'のようにして、一部だけ組み込むことも可能です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした