# [digits].my_digits(base)
# [digits].my_digits([base]) # ex. [9,33,21,1428].undigits([24,60,60]) #=> 123456789
# baseは数値または数値の配列
# ty 0:baseは基数, 1:baseは |ビット数|
class Array
def undigits(base=10,ty=0)
if base.is_a?(Array)
case ty
when 0
bs = [*base,1]
b = 1
return self.inject(0){|r,i|
if bs.empty?
# raise ArgumentError
return r
else
b *= bs.pop.abs
next b * i + r if i.is_a?(Integer)
# raise ArgumentError
r
end
}
when 1
bs = base.dup
b = 0
return self.inject(0){|r,i|
if bs.empty?
# raise ArgumentError
return r
else
ab = bs.pop.abs
val = r | ((i & (1 << ab) - 1) << b)
b += ab
next val
end
}
end
raise ArgumentError, 'type'
end
raise( ArgumentError, 'base' ) if base.is_a?(Integer).!
case ty
when 0
raise( ArgumentError, 'base' ) if base <= 1
return self.reverse.inject(0){|r,i|
next base * r + i if i.is_a?(Integer)
# raise ArgumentError
r
}
when 1
raise( ArgumentError, 'base' ) if base == 0
ab = base.abs
msk = (1 << ab) - 1
b = 0
return self.inject(0){|r,i|
# raise ArgumentError unles i.is_a?(Integer)
next r unless i.is_a?(Integer)
r += (i & msk) << b
b += ab
r
}
else
raise ArgumentError
end
end
alias_method :to_i, :undigits
end
# baseは数値または数値の配列
# ty 0:baseは基数, 1:baseはビット数、負のビット数は符号拡張する
class Integer
def my_digits(base=10,ty=0)
v = self.to_i
raise ArgumentError if v < 0
if base.is_a?(Array)
return [0] if v == 0
case ty
when 0
bs = base.dup
r = []
while v > 0
if bs.empty?
r << v
break
else
b = bs.pop
v, n = v.divmod(b)
r << n
end
end
return r
when 1
bs = base.dup
r = []
while v > 0
if bs.empty?
# r << v
break
else
b = bs.pop
ab = b.abs
bv = v & ((1 << ab) - 1)
if b < 0
xt = 1 << ab-1
bv = (bv ^ xt) - xt
end
r << bv
v >>= ab
end
end
return r
end
raise ArgumentError
end
return [0] if v == 0
raise( ArgumentError, 'base' ) if base.is_a?(Integer).! # || base <= 1
ab = base.abs
if ty == 0 && ab & (ab-1) == 0 # 2のべき乗?
base = ab.bit_length - 1 # Math.log2(ab).round
ty = 1
ab = base # debug 2019/12/22 13:39 JST
end
r = []
case ty
when 0
raise( ArgumentError, 'base' ) if base <= 1
while v > 0
v, n = v.divmod(base)
r << n
end
return r
when 1
raise( ArgumentError, 'base' ) if base == 0
msk = (1 << ab) - 1
xt = 1 << ab - 1
while v > 0
r << ((base < 0)? ((v & msk) ^ xt) - xt : v & msk)
v >>= ab
end
return r
end
raise ArgumentError
end
end
# Hash#bits( bitFieldHash ) -> Integer
class Hash
def bits( h )
raise ArgumentError unless h.is_a?(Hash)
h.keys.reverse.map{|k| self[k] || 0 }.undigits( h.values, 1 )
end
end
# Integer#unbit( bitFieldHash ) -> {bitValue}
class Integer
def unbits( h )
raise ArgumentError unless h.is_a?(Hash)
v = self.my_digits( h.values, 1 )
v.push( *Array.new( h.size-v.size, 0 ) ) if v.size < h.size
Hash[ *h.keys.map{|ky| [ky,v.pop || 0] }.flatten ]
end
end
#####################################################################
# test v2 2019/12/26
module CheckRet_
def self.check( f_verbose = false, f_lineNo = false )
crb = Check_ret_bind_.new.instance_binding
fl = (f_verbose.is_a?(Hash))? f_verbose[:lineno] : f_lineNo
fv = (f_verbose.is_a?(Hash))? f_verbose[:verbose] : f_verbose
fl &&= fv
while buff = DATA.gets(chomp:true)
print "%5d: " % DATA.lineno if fl
case
when /^\s*([^#].*?)#=>(.*)$/ =~ buff
puts buff if fv
syn = $1.strip
val = $2.strip.sub(/\s*### .*$/,'')
begin
ans = eval( syn, crb )
rescue
puts "#{DATA.lineno}: #{$!}"
end
begin
if ans != eval( val, crb )
puts "*** Error : #{syn} #=> #{ans.inspect} != #{val} ***"
end
rescue
puts "#{DATA.lineno}:#=> #{$!}"
end
when /^#---/ =~ buff
puts if fl
break if /^#---\s*END\b/i =~ buff
when /^\s*#/ =~ buff
puts buff if fv
when buff != ''
puts buff if fv
begin
eval( buff, crb )
rescue
puts "#{DATA.lineno}: #{$!}"
end
else
puts buff if fv
end
end
end
private; class Check_ret_bind_; def instance_binding; binding end end
end
CheckRet_.check( lineno:true, verbose:true )
puts "Done."
__END__
[1, 1, 0, 1, 'hoge'].to_i(2) #=> 11
123456789.my_digits([24,60]) #=> [9, 21, 85733]
123456789.my_digits([24,60,60]) #=> [9,33,21,1428]
Bhms = [24,60,60]
[9,33,21,1428,'d h:m:s'].undigits(Bhms) #=> 123456789
123456789.my_digits(Bhms).undigits(Bhms) #=> 123456789
[9,33,21,1428, 9,9,9,9].undigits(Bhms) #=> 123456789
[9,33,21].undigits(Bhms) #=> 77589
[9,33].undigits(Bhms) #=> 1989
[9].undigits(Bhms) #=> 9
# ==== bit field test ====
0117.my_digits(8) #=> [7,1,1]
0117.my_digits(3,1) #=> [7,1,1] ### 上と同じ 8 == 2**3
[3,3,7].undigits(3,1).to_s(8) #=> "733"
[1,3,7,8,0xFFFF,-1].undigits(3,1).to_s(8) #=> "770731"
0b0011_100_01.my_digits([4,3,2],1) #=> [1,4,3]
[1,4,3].undigits([4,3,2],1).to_s(2) #=> "1110001"
0b0011_100_01.my_digits([-4,-3,-2],1) #=> [1,-4,3] ### (-4:符号拡張)
[1,-4,3].undigits([4,3,2],1).to_s(2) #=> "1110001"
[1,-4,3].undigits([-4,-3,-2],1).to_s(2) #=> "1110001" ### (bit数は絶対値)
0b001111_111_11.my_digits([-4,-3,-2],1) #=> [-1,-1,-1]
0b001110_110_10.my_digits([-4,-3,-2],1) #=> [-2,-2,-2]
0b001100_100_00.my_digits([-4,-3,-2],1) #=> [0,-4,-4]
0b011111_111_11.my_digits([-4,-3,-2],1) #=> [-1,-1,-1] ### (範囲外のビットは無視)
0b011110_110_10.my_digits([-4,-3,-2],1) #=> [-2,-2,-2]
0b011100_100_00.my_digits([-4,-3,-2],1) #=> [0,-4,-4]
0x0FFF.my_digits(-12,1) #=> [-1]
0x0FFF.my_digits([-12],1) #=> [-1]
[3,3,7].undigits(-3,1).to_s(8) #=> "733"
[9,33,21,1428].undigits([-24,-60,-60]) #=> 123456789 ### (これはraiseすべき?)
BFset = { foo:2, bar:3, car:3 } # ビットフィールド名とビット数
{}.bits( BFset ) #=> 0 ### 0b00_000_000
{ foo:1 }.bits( BFset ) #=> 0x40 ### 0b01_000_000
{ car:1, bar:2 }.bits( BFset ) #=> 17 ### 0b00_010_001
bh = 17.unbits( BFset ) #=> {foo:0, bar:2, car:1}
bh[ :foo ] = 3
bh #=> {:foo=>3, :bar=>2, :car=>1}
bh.bits( BFset ) #=> 209 ### 0b11_010_001
BFset2 = { foo:2, bar:-3, car:-3 }
bh = 0xFF.unbits( BFset2 ) #=> {foo:3, bar:-1, car:-1}
bh[ :car ] = 0
bh.bits( BFset ) #=> 0xF8 ### 0b11_111_000
IyBbZGlnaXRzXS5teV9kaWdpdHMoYmFzZSkKIyBbZGlnaXRzXS5teV9kaWdpdHMoW2Jhc2VdKQkJIyBleC4gWzksMzMsMjEsMTQyOF0udW5kaWdpdHMoWzI0LDYwLDYwXSkgIz0+IDEyMzQ1Njc4OQojIGJhc2Xjga/mlbDlgKTjgb7jgZ/jga/mlbDlgKTjga7phY3liJcKIyB0eSAwOmJhc2Xjga/ln7rmlbAsIDE6YmFzZeOBryB844OT44OD44OI5pWwfApjbGFzcyBBcnJheQoJZGVmIHVuZGlnaXRzKGJhc2U9MTAsdHk9MCkKCQlpZiBiYXNlLmlzX2E/KEFycmF5KQoJCQljYXNlIHR5CgkJCXdoZW4gMAoJCQkJYnMgPSBbKmJhc2UsMV0KCQkJCWIgPSAxCgkJCQlyZXR1cm4gc2VsZi5pbmplY3QoMCl7fHIsaXwKCQkJCQlpZiBicy5lbXB0eT8KIwkJCQkJCXJhaXNlIEFyZ3VtZW50RXJyb3IKCQkJCQkJcmV0dXJuIHIKCQkJCQllbHNlCgkJCQkJCWIgKj0gYnMucG9wLmFicwoJCQkJCQluZXh0IGIgKiBpICsgcglpZiBpLmlzX2E/KEludGVnZXIpCiMJCQkJCQlyYWlzZSBBcmd1bWVudEVycm9yCgkJCQkJCXIKCQkJCQllbmQKCQkJCX0KCQkJd2hlbiAxCgkJCQlicyA9IGJhc2UuZHVwCgkJCQliID0gMAoJCQkJcmV0dXJuIHNlbGYuaW5qZWN0KDApe3xyLGl8CgkJCQkJaWYgYnMuZW1wdHk/CiMJCQkJCQlyYWlzZSBBcmd1bWVudEVycm9yCgkJCQkJCXJldHVybiByCgkJCQkJZWxzZQoJCQkJCQlhYiA9IGJzLnBvcC5hYnMKCQkJCQkJdmFsID0gIHIgfCAoKGkgJiAoMSA8PCBhYikgLSAxKSA8PCBiKQoJCQkJCQliICs9IGFiCgkJCQkJCW5leHQgdmFsCgkJCQkJZW5kCgkJCQl9CgkJCWVuZAoJCQlyYWlzZSBBcmd1bWVudEVycm9yLCAndHlwZScKCQllbmQKCQlyYWlzZSggQXJndW1lbnRFcnJvciwgJ2Jhc2UnICkJaWYgYmFzZS5pc19hPyhJbnRlZ2VyKS4hCgkJY2FzZSB0eQoJCXdoZW4gMAoJCQlyYWlzZSggQXJndW1lbnRFcnJvciwgJ2Jhc2UnICkJaWYgYmFzZSA8PSAxCgkJCXJldHVybiBzZWxmLnJldmVyc2UuaW5qZWN0KDApe3xyLGl8CgkJCQluZXh0IGJhc2UgKiByICsgaQlpZiBpLmlzX2E/KEludGVnZXIpCiMJCQkJcmFpc2UgQXJndW1lbnRFcnJvcgoJCQkJcgoJCQl9CgkJd2hlbiAxCgkJCXJhaXNlKCBBcmd1bWVudEVycm9yLCAnYmFzZScgKQlpZiBiYXNlID09IDAKCQkJYWIgPSBiYXNlLmFicwoJCQltc2sgPSAoMSA8PCBhYikgLSAxCgkJCWIgPSAwCgkJCXJldHVybiBzZWxmLmluamVjdCgwKXt8cixpfAojCQkJCXJhaXNlIEFyZ3VtZW50RXJyb3IJdW5sZXMgaS5pc19hPyhJbnRlZ2VyKQoJCQkJbmV4dCByCXVubGVzcyBpLmlzX2E/KEludGVnZXIpCgkJCQlyICs9IChpICYgbXNrKSA8PCBiCgkJCQliICs9IGFiCgkJCQlyCgkJCX0KCQllbHNlCgkJCXJhaXNlIEFyZ3VtZW50RXJyb3IKCQllbmQKCWVuZAoJYWxpYXNfbWV0aG9kIDp0b19pLCA6dW5kaWdpdHMKZW5kCgojIGJhc2Xjga/mlbDlgKTjgb7jgZ/jga/mlbDlgKTjga7phY3liJcKIyB0eSAwOmJhc2Xjga/ln7rmlbAsIDE6YmFzZeOBr+ODk+ODg+ODiOaVsOOAgeiyoOOBruODk+ODg+ODiOaVsOOBr+espuWPt+aLoeW8teOBmeOCiwpjbGFzcyBJbnRlZ2VyCglkZWYgbXlfZGlnaXRzKGJhc2U9MTAsdHk9MCkKCQl2ID0gc2VsZi50b19pCgkJcmFpc2UgQXJndW1lbnRFcnJvcglpZiB2IDwgMAoJCWlmIGJhc2UuaXNfYT8oQXJyYXkpCgkJCXJldHVybiBbMF0JaWYgdiA9PSAwCgkJCWNhc2UgdHkKCQkJd2hlbiAwCgkJCQlicyA9IGJhc2UuZHVwCgkJCQlyID0gW10KCQkJCXdoaWxlIHYgPiAwCgkJCQkJaWYgYnMuZW1wdHk/CgkJCQkJCXIgPDwgdgoJCQkJCQlicmVhawoJCQkJCWVsc2UKCQkJCQkJYiA9IGJzLnBvcAoJCQkJCQl2LCBuID0gdi5kaXZtb2QoYikKCQkJCQkJciA8PCBuCgkJCQkJZW5kCgkJCQllbmQKCQkJCXJldHVybiByCgkJCXdoZW4gMQoJCQkJYnMgPSBiYXNlLmR1cAoJCQkJciA9IFtdCgkJCQl3aGlsZSB2ID4gMAoJCQkJCWlmIGJzLmVtcHR5PwojCQkJCQkJciA8PCB2CgkJCQkJCWJyZWFrCgkJCQkJZWxzZQoJCQkJCQliID0gYnMucG9wCgkJCQkJCWFiID0gYi5hYnMKCQkJCQkJYnYgPSB2ICYgKCgxIDw8IGFiKSAtIDEpCgkJCQkJCWlmIGIgPCAwCgkJCQkJCQl4dCA9IDEgPDwgYWItMQoJCQkJCQkJYnYgPSAoYnYgXiB4dCkgLSB4dAoJCQkJCQllbmQKCQkJCQkJciA8PCBidgoJCQkJCQl2ID4+PSBhYgoJCQkJCWVuZAoJCQkJZW5kCgkJCQlyZXR1cm4gcgoJCQllbmQKCQkJcmFpc2UgQXJndW1lbnRFcnJvcgoJCWVuZAoJCXJldHVybiBbMF0JaWYgdiA9PSAwCgkJcmFpc2UoIEFyZ3VtZW50RXJyb3IsICdiYXNlJyApCWlmIGJhc2UuaXNfYT8oSW50ZWdlcikuISAjIHx8IGJhc2UgPD0gMQoJCWFiID0gYmFzZS5hYnMKCQlpZiB0eSA9PSAwICYmIGFiICYgKGFiLTEpID09IDAJIyAy44Gu44G544GN5LmXPwoJCQliYXNlID0gYWIuYml0X2xlbmd0aCAtIDEJIyBNYXRoLmxvZzIoYWIpLnJvdW5kCgkJCXR5ID0gMQoJCQlhYiA9IGJhc2UJCSMgZGVidWcgMjAxOS8xMi8yMiAxMzozOSBKU1QKCQllbmQKCQlyID0gW10KCQljYXNlIHR5CgkJd2hlbiAwCgkJCXJhaXNlKCBBcmd1bWVudEVycm9yLCAnYmFzZScgKQlpZiBiYXNlIDw9IDEKCQkJd2hpbGUgdiA+IDAKCQkJCXYsIG4gPSB2LmRpdm1vZChiYXNlKQoJCQkJciA8PCBuCgkJCWVuZAoJCQlyZXR1cm4gcgoJCXdoZW4gMQoJCQlyYWlzZSggQXJndW1lbnRFcnJvciwgJ2Jhc2UnICkJaWYgYmFzZSA9PSAwCgkJCW1zayA9ICgxIDw8IGFiKSAtIDEKCQkJeHQgPSAxIDw8IGFiIC0gMQoJCQl3aGlsZSB2ID4gMAoJCQkJciA8PCAoKGJhc2UgPCAwKT8gKCh2ICYgbXNrKSBeIHh0KSAtIHh0IDogdiAmIG1zaykKCQkJCXYgPj49IGFiCgkJCWVuZAoJCQlyZXR1cm4gcgoJCWVuZAoJCXJhaXNlIEFyZ3VtZW50RXJyb3IKCWVuZAplbmQKCiMgCUhhc2gjYml0cyggYml0RmllbGRIYXNoICkgLT4gSW50ZWdlcgpjbGFzcyBIYXNoCglkZWYgYml0cyggaCApCgkJcmFpc2UgQXJndW1lbnRFcnJvcgl1bmxlc3MgaC5pc19hPyhIYXNoKQoJCWgua2V5cy5yZXZlcnNlLm1hcHt8a3wgc2VsZltrXSB8fCAwIH0udW5kaWdpdHMoIGgudmFsdWVzLCAxICkKCWVuZAplbmQKCiMgSW50ZWdlciN1bmJpdCggYml0RmllbGRIYXNoICkgLT4ge2JpdFZhbHVlfQpjbGFzcyBJbnRlZ2VyCglkZWYgdW5iaXRzKCBoICkKCQlyYWlzZSBBcmd1bWVudEVycm9yCXVubGVzcyBoLmlzX2E/KEhhc2gpCgkJdiA9IHNlbGYubXlfZGlnaXRzKCBoLnZhbHVlcywgMSApCgkJdi5wdXNoKCAqQXJyYXkubmV3KCBoLnNpemUtdi5zaXplLCAwICkgKQlpZiB2LnNpemUgPCBoLnNpemUKCQlIYXNoWyAqaC5rZXlzLm1hcHt8a3l8IFtreSx2LnBvcCB8fCAwXSB9LmZsYXR0ZW4gXQoJZW5kCmVuZAoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgojIHRlc3QgdjIgMjAxOS8xMi8yNgptb2R1bGUgQ2hlY2tSZXRfCglkZWYgc2VsZi5jaGVjayggZl92ZXJib3NlID0gZmFsc2UsIGZfbGluZU5vID0gZmFsc2UgKQoJCWNyYiA9IENoZWNrX3JldF9iaW5kXy5uZXcuaW5zdGFuY2VfYmluZGluZwoJCWZsID0gKGZfdmVyYm9zZS5pc19hPyhIYXNoKSk/IGZfdmVyYm9zZVs6bGluZW5vXSAgOiBmX2xpbmVObwoJCWZ2ID0gKGZfdmVyYm9zZS5pc19hPyhIYXNoKSk/IGZfdmVyYm9zZVs6dmVyYm9zZV0gOiBmX3ZlcmJvc2UKCQlmbCAmJj0gZnYKCQl3aGlsZSBidWZmID0gREFUQS5nZXRzKGNob21wOnRydWUpCgkJCXByaW50ICIlNWQ6ICIgJSBEQVRBLmxpbmVubwlpZiBmbAoJCQljYXNlCgkJCXdoZW4gL15ccyooW14jXS4qPykjPT4oLiopJC8gPX4gYnVmZgoJCQkJcHV0cyBidWZmCWlmIGZ2CgkJCQlzeW4gPSAkMS5zdHJpcAoJCQkJdmFsID0gJDIuc3RyaXAuc3ViKC9ccyojIyMgLiokLywnJykKCQkJCWJlZ2luCgkJCQkJYW5zID0gZXZhbCggc3luLCBjcmIgKQoJCQkJcmVzY3VlCgkJCQkJcHV0cyAiI3tEQVRBLmxpbmVub306ICN7JCF9IgoJCQkJZW5kCgkJCQliZWdpbgoJCQkJCWlmIGFucyAhPSBldmFsKCB2YWwsIGNyYiApCgkJCQkJCXB1dHMgIioqKiBFcnJvciA6ICN7c3lufSAjPT4gI3thbnMuaW5zcGVjdH0gIT0gI3t2YWx9ICoqKiIKCQkJCQllbmQKCQkJCXJlc2N1ZQoJCQkJCXB1dHMgIiN7REFUQS5saW5lbm99OiM9PiAjeyQhfSIKCQkJCWVuZAoJCQl3aGVuIC9eIy0tLS8gPX4gYnVmZgoJCQkJcHV0cwlpZiBmbAoJCQkJYnJlYWsJaWYgL14jLS0tXHMqRU5EXGIvaSA9fiBidWZmCgkJCXdoZW4gL15ccyojLyA9fiBidWZmCgkJCQlwdXRzIGJ1ZmYJaWYgZnYKCQkJd2hlbiBidWZmICE9ICcnCgkJCQlwdXRzIGJ1ZmYJaWYgZnYKCQkJCWJlZ2luCgkJCQkJZXZhbCggYnVmZiwgY3JiICApCgkJCQlyZXNjdWUKCQkJCQlwdXRzICIje0RBVEEubGluZW5vfTogI3skIX0iCgkJCQllbmQKCQkJZWxzZQoJCQkJcHV0cyBidWZmCWlmIGZ2CgkJCWVuZAoJCWVuZAoJZW5kCgoJcHJpdmF0ZTsgY2xhc3MgQ2hlY2tfcmV0X2JpbmRfOyBkZWYgaW5zdGFuY2VfYmluZGluZzsgYmluZGluZyBlbmQgZW5kCmVuZAoKCUNoZWNrUmV0Xy5jaGVjayggbGluZW5vOnRydWUsIHZlcmJvc2U6dHJ1ZSApCglwdXRzICJEb25lLiIKCl9fRU5EX18KCVsxLCAxLCAwLCAxLCAnaG9nZSddLnRvX2koMikJIz0+IDExCgkxMjM0NTY3ODkubXlfZGlnaXRzKFsyNCw2MF0pCSM9PiBbOSwgMjEsIDg1NzMzXQoJMTIzNDU2Nzg5Lm15X2RpZ2l0cyhbMjQsNjAsNjBdKQkjPT4gWzksMzMsMjEsMTQyOF0KCglCaG1zID0gWzI0LDYwLDYwXQoJWzksMzMsMjEsMTQyOCwnZCBoOm06cyddLnVuZGlnaXRzKEJobXMpCQkjPT4gMTIzNDU2Nzg5CgkxMjM0NTY3ODkubXlfZGlnaXRzKEJobXMpLnVuZGlnaXRzKEJobXMpCSM9PiAxMjM0NTY3ODkKCVs5LDMzLDIxLDE0MjgsIDksOSw5LDldLnVuZGlnaXRzKEJobXMpCQkjPT4gMTIzNDU2Nzg5CglbOSwzMywyMV0udW5kaWdpdHMoQmhtcykgCSM9PiA3NzU4OQoJWzksMzNdLnVuZGlnaXRzKEJobXMpCQkjPT4gMTk4OQoJWzldLnVuZGlnaXRzKEJobXMpCQkJIz0+IDkKCiMgPT09PSBiaXQgZmllbGQgdGVzdCA9PT09CgoJMDExNy5teV9kaWdpdHMoOCkJCSM9PiBbNywxLDFdCgkwMTE3Lm15X2RpZ2l0cygzLDEpCQkjPT4gWzcsMSwxXSAjIyMg5LiK44Go5ZCM44GYIDggPT0gMioqMwoKCVszLDMsN10udW5kaWdpdHMoMywxKS50b19zKDgpCSM9PiAiNzMzIgoJWzEsMyw3LDgsMHhGRkZGLC0xXS51bmRpZ2l0cygzLDEpLnRvX3MoOCkJIz0+ICI3NzA3MzEiCgoJMGIwMDExXzEwMF8wMS5teV9kaWdpdHMoWzQsMywyXSwxKQkjPT4gWzEsNCwzXQoJWzEsNCwzXS51bmRpZ2l0cyhbNCwzLDJdLDEpLnRvX3MoMikJIz0+ICIxMTEwMDAxIgoJMGIwMDExXzEwMF8wMS5teV9kaWdpdHMoWy00LC0zLC0yXSwxKQkjPT4gWzEsLTQsM10gIyMjICgtNDrnrKblj7fmi6HlvLUpCglbMSwtNCwzXS51bmRpZ2l0cyhbNCwzLDJdLDEpLnRvX3MoMikJIz0+ICIxMTEwMDAxIgoJWzEsLTQsM10udW5kaWdpdHMoWy00LC0zLC0yXSwxKS50b19zKDIpCSM9PiAiMTExMDAwMSIgIyMjIChiaXTmlbDjga/ntbblr77lgKQpCgoJMGIwMDExMTFfMTExXzExLm15X2RpZ2l0cyhbLTQsLTMsLTJdLDEpCSM9PiBbLTEsLTEsLTFdCgkwYjAwMTExMF8xMTBfMTAubXlfZGlnaXRzKFstNCwtMywtMl0sMSkJIz0+IFstMiwtMiwtMl0KCTBiMDAxMTAwXzEwMF8wMC5teV9kaWdpdHMoWy00LC0zLC0yXSwxKQkjPT4gWzAsLTQsLTRdCgoJMGIwMTExMTFfMTExXzExLm15X2RpZ2l0cyhbLTQsLTMsLTJdLDEpCSM9PiBbLTEsLTEsLTFdICMjIyAo56+E5Zuy5aSW44Gu44OT44OD44OI44Gv54Sh6KaWKQoJMGIwMTExMTBfMTEwXzEwLm15X2RpZ2l0cyhbLTQsLTMsLTJdLDEpCSM9PiBbLTIsLTIsLTJdCgkwYjAxMTEwMF8xMDBfMDAubXlfZGlnaXRzKFstNCwtMywtMl0sMSkJIz0+IFswLC00LC00XQoKCTB4MEZGRi5teV9kaWdpdHMoLTEyLDEpCQkJIz0+IFstMV0KCTB4MEZGRi5teV9kaWdpdHMoWy0xMl0sMSkJCSM9PiBbLTFdCglbMywzLDddLnVuZGlnaXRzKC0zLDEpLnRvX3MoOCkJIz0+ICI3MzMiCglbOSwzMywyMSwxNDI4XS51bmRpZ2l0cyhbLTI0LC02MCwtNjBdKQkjPT4gMTIzNDU2Nzg5ICMjIyAo44GT44KM44GvcmFpc2XjgZnjgbnjgY0/KQoKCglCRnNldCA9IHsgZm9vOjIsIGJhcjozLCBjYXI6MyB9CQkjIOODk+ODg+ODiOODleOCo+ODvOODq+ODieWQjeOBqOODk+ODg+ODiOaVsAoJe30uYml0cyggQkZzZXQgKQkJCQkJIz0+IDAgICAgIyMjIDBiMDBfMDAwXzAwMAoJeyBmb286MSB9LmJpdHMoIEJGc2V0ICkJCQkJIz0+IDB4NDAgIyMjIDBiMDFfMDAwXzAwMAoJeyBjYXI6MSwgYmFyOjIgfS5iaXRzKCBCRnNldCApCQkjPT4gMTcgICAjIyMgMGIwMF8wMTBfMDAxCgliaCA9IDE3LnVuYml0cyggQkZzZXQgKSAJCQkjPT4ge2ZvbzowLCBiYXI6MiwgY2FyOjF9CgliaFsgOmZvbyBdID0gMwoJYmgJCQkJCQkJCQkjPT4gezpmb289PjMsIDpiYXI9PjIsIDpjYXI9PjF9CgliaC5iaXRzKCBCRnNldCApCQkJCQkjPT4gMjA5ICAjIyMgMGIxMV8wMTBfMDAxCgoJQkZzZXQyID0geyBmb286MiwgYmFyOi0zLCBjYXI6LTMgfQoJYmggPSAweEZGLnVuYml0cyggQkZzZXQyICkgCQkJIz0+IHtmb286MywgYmFyOi0xLCBjYXI6LTF9CgliaFsgOmNhciBdID0gMAoJYmguYml0cyggQkZzZXQgKQkJCQkJIz0+IDB4RjggICMjIyAwYjExXzExMV8wMDAK
215: [1, 1, 0, 1, 'hoge'].to_i(2) #=> 11
216: 123456789.my_digits([24,60]) #=> [9, 21, 85733]
217: 123456789.my_digits([24,60,60]) #=> [9,33,21,1428]
218:
219: Bhms = [24,60,60]
220: [9,33,21,1428,'d h:m:s'].undigits(Bhms) #=> 123456789
221: 123456789.my_digits(Bhms).undigits(Bhms) #=> 123456789
222: [9,33,21,1428, 9,9,9,9].undigits(Bhms) #=> 123456789
223: [9,33,21].undigits(Bhms) #=> 77589
224: [9,33].undigits(Bhms) #=> 1989
225: [9].undigits(Bhms) #=> 9
226:
227: # ==== bit field test ====
228:
229: 0117.my_digits(8) #=> [7,1,1]
230: 0117.my_digits(3,1) #=> [7,1,1] ### 上と同じ 8 == 2**3
231:
232: [3,3,7].undigits(3,1).to_s(8) #=> "733"
233: [1,3,7,8,0xFFFF,-1].undigits(3,1).to_s(8) #=> "770731"
234:
235: 0b0011_100_01.my_digits([4,3,2],1) #=> [1,4,3]
236: [1,4,3].undigits([4,3,2],1).to_s(2) #=> "1110001"
237: 0b0011_100_01.my_digits([-4,-3,-2],1) #=> [1,-4,3] ### (-4:符号拡張)
238: [1,-4,3].undigits([4,3,2],1).to_s(2) #=> "1110001"
239: [1,-4,3].undigits([-4,-3,-2],1).to_s(2) #=> "1110001" ### (bit数は絶対値)
240:
241: 0b001111_111_11.my_digits([-4,-3,-2],1) #=> [-1,-1,-1]
242: 0b001110_110_10.my_digits([-4,-3,-2],1) #=> [-2,-2,-2]
243: 0b001100_100_00.my_digits([-4,-3,-2],1) #=> [0,-4,-4]
244:
245: 0b011111_111_11.my_digits([-4,-3,-2],1) #=> [-1,-1,-1] ### (範囲外のビットは無視)
246: 0b011110_110_10.my_digits([-4,-3,-2],1) #=> [-2,-2,-2]
247: 0b011100_100_00.my_digits([-4,-3,-2],1) #=> [0,-4,-4]
248:
249: 0x0FFF.my_digits(-12,1) #=> [-1]
250: 0x0FFF.my_digits([-12],1) #=> [-1]
251: [3,3,7].undigits(-3,1).to_s(8) #=> "733"
252: [9,33,21,1428].undigits([-24,-60,-60]) #=> 123456789 ### (これはraiseすべき?)
253:
254:
255: BFset = { foo:2, bar:3, car:3 } # ビットフィールド名とビット数
256: {}.bits( BFset ) #=> 0 ### 0b00_000_000
257: { foo:1 }.bits( BFset ) #=> 0x40 ### 0b01_000_000
258: { car:1, bar:2 }.bits( BFset ) #=> 17 ### 0b00_010_001
259: bh = 17.unbits( BFset ) #=> {foo:0, bar:2, car:1}
260: bh[ :foo ] = 3
261: bh #=> {:foo=>3, :bar=>2, :car=>1}
262: bh.bits( BFset ) #=> 209 ### 0b11_010_001
263:
264: BFset2 = { foo:2, bar:-3, car:-3 }
265: bh = 0xFF.unbits( BFset2 ) #=> {foo:3, bar:-1, car:-1}
266: bh[ :car ] = 0
267: bh.bits( BFset ) #=> 0xF8 ### 0b11_111_000
Done.