Ruby で each 実装
each ブロックの実装楽しい。
def each @data.each_byte { |byte| (0..7).each { |bit_offset| bit = (byte >> (7 - bit_offset)) & 1 yield(bit) } } end
class に↑こう書いておくだけで、
$io.each { |b| printf("%d", b) }
こんな風に 1 bit ずつ each で回せる。うーむw
ord の問題
ついでに、ord の問題も、 Rubyのバージョンで分岐させて 1.8 でも動くようにしてみた。
if RUBY_VERSION >= '1.9.0' # >_<; byte = @data[byte_offset].ord else byte = @data[byte_offset] end
2の補数
n bit 取るメソッドで、負の値を扱えるようにしてみた。
def get_bits_signed!(bit_width) bits = get_bits!(bit_width) sig_b = 1 << (bit_width - 1) if (sig_b & bits) # negaive bit_mask = (sig_b << 1) - 1 bits = bits ^ bit_mask; # bit reverse bits = - (bits + 1) end bits end
例えば、11bitなんだけど符号付きだよ。みたいな変態的なバイナリフォーマットを扱うときに必要。
補足 (2009/08/19)
if (sig_b & bits) # negaive
↑これは間違い。↓こう直した。
if ((sig_b & bits) != 0) # negaive