10進数を2進数に直すなど。
まずは10進数の1桁1桁を分解する方法を考えてみる。
例えば2011を1桁ずつ分解するには、
2011 を10で割って 余り1 201 を10で割って 余り1 20 を10で割って 余り0 2 を10で割って 余り2
以上を逆順に並べて 2, 0, 1, 1 となる。上の桁から取り出すより下の桁から取りだす方が簡単。
同様に2進数の場合も2で割って余りを逆順に並べてみる。
2進数の場合は、余りの計算を 1 との論理積、2で割るのをビットシフトすれば1桁ずつ取り出せる。perlでやるとこんな感じ。
my $n = 2011; my @bin = (); while (0 < $n) { unshift @bin, $n & 0b1; $n = $n >> 1; } print join ',', @bin;
16進数の場合も、0xFとの論理積、4ビットシフトすれば1桁ずつ取り出せる。
my $n = 2011; my @char = [0..9,'A'..'F']; my $result = '' while (0 < $n) { $result = $char[$n & 0xF].$result; $n = $n >> 4; } print join ',', @hex;
16進数は、2進数表現を4桁分をまとめて1文字にすることに等しい。0xFというのは16進数の1桁の最大値2進数の4桁分を1で埋めた数。これと論理積を取ることで16進数下位1桁分の値を取りだすことができる。
同様に8進数は3桁分をまとめて1文字にすることに等しく、2進数3桁分を1で埋めた7と論理積を取ることで8進数下位1桁分の値を取りだすことができる。
0〜9,'A'〜''Z'でやる36進数とかは、剰余を取る方法になってしまうかな。
いじょ。
頭の整理というか、10進数を2進数に変換する方法をぐぐると剰余の方法が書いてあったのでもやっとしてやってみた。
http://vita-home.net/?p=234
perlでやるなら↑こちらのやり方が簡単。
[追記]
手元の環境(OSX 10.7.2)では0x1000000000000000(16桁)と0x10000000000000000(17桁)とを1と論理積とって見たところ、16桁の方は期待通り0になるけど17桁の方は1になった。内部の表現方法が変わってしまう為だと思われる。