=begin
> お題:与えられた正の整数nを2進数~16進数に変換して表示する。
> 11進数以降の10以上を表す文字はABCDEFを使用。
> (10=A, 11=B, 12=C, 13=D, 14=E, 15=F)
> 例:12進数の11 ---> B
整数だと面白くないので実数でやる。
検査のために逆関数も作っとく。
2進数~64進数の Base64もどき。
# 1/3の3進とか、Piの2進とかやってみたかった。
=end
Nstr = *'0'..'9', *'A'..'Z', *'a'..'z', '+', '/' # Base64 もどき
Nidx = {}
Nstr.each_with_index{|ch,idx| Nidx[ch] = idx }
def fbase( bs, n )
return nil if bs < 2 || bs > Nstr.size
str = ''
sgn = (n < 0)? '-' : ''
n = n.abs
fr = n - n.to_i
n = n.to_i
begin
n, r = n.divmod( bs )
str << Nstr[r]
end while n != 0
fdig = Math.log( 10 ** 8, bs ).to_i + 1
fstr = '.'
begin
fr *= bs
fstr << Nstr[fr.to_i]
fr -= fr.to_i
fdig -= 1
end while fr != 0 && fdig > 0
fstr.sub!( /0+$/, '' )
fstr = '' if fstr == '.'
"#{sgn}#{str.reverse}#{fstr}"
end
def revfbase( bs, str )
return nil if bs < 2 || bs > Nstr.size
fstr = ''
if str =~ /^(.*)\.(.*)$/
str = $1
fstr = $2
end
sg = 1
if str[0] == '-'
sg = -1
str = str[1..-1]
end
n = 0
m = 1
str.reverse.each_char{|ch|
unless Nidx[ch]
warn "*** #{ch} ***"
return ''
end
n += m * Nidx[ch]
m *= bs
}
m = 1
fstr.each_char{|ch|
unless Nidx[ch]
warn "*** #{ch} ***"
return ''
end
m = m.fdiv(bs)
n += m * Nidx[ch]
}
sg * n
end
def ftest( bs, n )
return if bs < 2 || bs > Nstr.size
print "%20s : " % n
ans = fbase( bs, n )
print "#{'%2d' % bs} : #{'%20s' % ans}"
str = revfbase( bs, ans )
print " : #{'%20s' % str}"
if n != str.to_f
print " : #{'%.1e' % [n - str.to_f]}"
end
puts
end
ftest( 2, 123456 )
ftest( 10, 123456 )
ftest( 16, 123456 )
ftest( 64, 123456 )
ftest( 10, -123456 )
ftest( 2, -123456 )
ftest( 2, 0 )
ftest( 2, 2.5 )
ftest( 2, 0.5 )
ftest( 2, 0.25 )
ftest( 2, 0.125 )
ftest( 2, -0.125 )
ftest( 2, 0.75 )
ftest( 2, 1.41421356 )
ftest( 2, 3.1415926 )
ftest( 3, 3.1415926 )
ftest( 10, 3.1415926 )
ftest( 16, 3.1415926 )
ftest( 64, 3.1415926 )
ftest( 16, 10.75 )
ftest( 3, 1.fdiv(3) )
ftest( 6, 1.fdiv(3) )
ftest( 9, 1.fdiv(3) )
ftest( 63, 1.fdiv(3) )
PWJlZ2luCgo+IOOBiumhjO+8muS4juOBiOOCieOCjOOBn+ato+OBruaVtOaVsG7jgpIy6YCy5pWw772eMTbpgLLmlbDjgavlpInmj5vjgZfjgabooajnpLrjgZnjgovjgIIKPiAxMemAsuaVsOS7pemZjeOBrjEw5Lul5LiK44KS6KGo44GZ5paH5a2X44GvQUJDREVG44KS5L2/55So44CCCj4g77yIMTA9QSwgMTE9QiwgMTI9QywgMTM9RCwgMTQ9RSwgMTU9Ru+8iQo+IOS+i++8mjEy6YCy5pWw44GuMTEgLS0tPiBCCgrmlbTmlbDjgaDjgajpnaLnmb3jgY/jgarjgYTjga7jgaflrp/mlbDjgafjgoTjgovjgIIK5qSc5p+744Gu44Gf44KB44Gr6YCG6Zai5pWw44KC5L2c44Gj44Go44GP44CCCjLpgLLmlbDvvZ42NOmAsuaVsOOBriBCYXNlNjTjgoLjganjgY3jgIIKCiMgMS8z44GuM+mAsuOBqOOBi+OAgVBp44GuMumAsuOBqOOBi+OChOOBo+OBpuOBv+OBn+OBi+OBo+OBn+OAggoKPWVuZAoKTnN0ciA9IConMCcuLic5JywgKidBJy4uJ1onLCAqJ2EnLi4neicsICcrJywgJy8nCSMgQmFzZTY0IOOCguOBqeOBjQpOaWR4ID0ge30KTnN0ci5lYWNoX3dpdGhfaW5kZXh7fGNoLGlkeHwgTmlkeFtjaF0gPSBpZHggfQoKCmRlZiBmYmFzZSggYnMsIG4gKQoJcmV0dXJuIG5pbAlpZiBicyA8IDIgfHwgYnMgPiBOc3RyLnNpemUKCXN0ciA9ICcnCglzZ24gPSAobiA8IDApPyAnLScgOiAnJwoJbiA9IG4uYWJzCglmciA9IG4gLSBuLnRvX2kKCW4gPSBuLnRvX2kKCWJlZ2luCgkJbiwgciA9IG4uZGl2bW9kKCBicyApCgkJc3RyIDw8IE5zdHJbcl0KCWVuZCB3aGlsZSBuICE9IDAKCglmZGlnID0gTWF0aC5sb2coIDEwICoqIDgsIGJzICkudG9faSArIDEKCglmc3RyID0gJy4nCgliZWdpbgoJCWZyICo9IGJzCgkJZnN0ciA8PCBOc3RyW2ZyLnRvX2ldCgkJZnIgLT0gZnIudG9faQoJCWZkaWcgLT0gMQoJZW5kIHdoaWxlIGZyICE9IDAgJiYgZmRpZyA+IDAKCWZzdHIuc3ViISggLzArJC8sICcnICkKCWZzdHIgPSAnJwlpZiBmc3RyID09ICcuJwoKCSIje3Nnbn0je3N0ci5yZXZlcnNlfSN7ZnN0cn0iCmVuZAoKZGVmIHJldmZiYXNlKCBicywgc3RyICkKCXJldHVybiBuaWwJaWYgYnMgPCAyIHx8IGJzID4gTnN0ci5zaXplCglmc3RyID0gJycKCWlmIHN0ciA9fiAvXiguKilcLiguKikkLwoJCXN0ciA9ICQxCgkJZnN0ciA9ICQyCgllbmQKCXNnID0gMQoJaWYgc3RyWzBdID09ICctJwoJCXNnID0gLTEKCQlzdHIgPSBzdHJbMS4uLTFdCgllbmQKCW4gPSAwCgltID0gMQoJc3RyLnJldmVyc2UuZWFjaF9jaGFye3xjaHwKCQl1bmxlc3MgTmlkeFtjaF0KCQkJd2FybiAiKioqICN7Y2h9ICoqKiIKCQkJcmV0dXJuICcnCgkJZW5kCgkJbiArPSBtICogTmlkeFtjaF0KCQltICo9IGJzCgl9CgltID0gMQoJZnN0ci5lYWNoX2NoYXJ7fGNofAoJCXVubGVzcyBOaWR4W2NoXQoJCQl3YXJuICIqKiogI3tjaH0gKioqIgoJCQlyZXR1cm4gJycKCQllbmQKCQltID0gbS5mZGl2KGJzKQoJCW4gKz0gbSAqIE5pZHhbY2hdCgl9CglzZyAqIG4KZW5kCgpkZWYgZnRlc3QoIGJzLCBuICkKCXJldHVybglpZiBicyA8IDIgfHwgYnMgPiBOc3RyLnNpemUKCXByaW50ICIlMjBzIDogIiAlIG4KCWFucyA9IGZiYXNlKCAgYnMsIG4gKQoJcHJpbnQgIiN7JyUyZCcgJSBic30gOiAjeyclMjBzJyAlIGFuc30iCglzdHIgPSByZXZmYmFzZSggYnMsIGFucyApCglwcmludCAiIDogI3snJTIwcycgJSBzdHJ9IgoJaWYgbiAhPSBzdHIudG9fZgoJCXByaW50ICIgOiAjeyclLjFlJyAlIFtuIC0gc3RyLnRvX2ZdfSIKCWVuZAoJcHV0cwplbmQKCgoJZnRlc3QoICAyLCAxMjM0NTYgKQoJZnRlc3QoIDEwLCAxMjM0NTYgKQoJZnRlc3QoIDE2LCAxMjM0NTYgKQoJZnRlc3QoIDY0LCAxMjM0NTYgKQoJZnRlc3QoIDEwLCAtMTIzNDU2ICkKCWZ0ZXN0KCAgMiwgLTEyMzQ1NiApCgoJZnRlc3QoICAyLCAwICkKCWZ0ZXN0KCAgMiwgMi41ICkKCWZ0ZXN0KCAgMiwgMC41ICkKCWZ0ZXN0KCAgMiwgMC4yNSApCglmdGVzdCggIDIsIDAuMTI1ICkKCWZ0ZXN0KCAgMiwgLTAuMTI1ICkKCWZ0ZXN0KCAgMiwgMC43NSApCgoJZnRlc3QoICAyLCAxLjQxNDIxMzU2ICkKCWZ0ZXN0KCAgMiwgMy4xNDE1OTI2ICkKCWZ0ZXN0KCAgMywgMy4xNDE1OTI2ICkKCWZ0ZXN0KCAxMCwgMy4xNDE1OTI2ICkKCWZ0ZXN0KCAxNiwgMy4xNDE1OTI2ICkKCWZ0ZXN0KCA2NCwgMy4xNDE1OTI2ICkKCglmdGVzdCggMTYsIDEwLjc1ICkKCglmdGVzdCggIDMsIDEuZmRpdigzKSApCglmdGVzdCggIDYsIDEuZmRpdigzKSApCglmdGVzdCggIDksIDEuZmRpdigzKSApCglmdGVzdCggNjMsIDEuZmRpdigzKSApCg==