4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rubyでのビット操作向けGem

Posted at

この前に、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'のようにして、一部だけ組み込むことも可能です。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?