16進数と10進数の変換

2進数とは

 現在のコンピュータは、全てのデータを0と1だけで表している事は御存じでしょうか。
 数字が0と1の二つしかないので、1に1を加えると桁が繰り上がって10になります。このような数値を「2進数」といいます。2進数の10に1を足すと11、更に足すとまた桁が繰り上がって100となります。100を普段使っている「10進数」で表すと4となります。
 これを表にすると以下のようになります。

2進数0110100100010000100000100000010000000100000000
10進数01248163264128256

 10進数の部分が、2^(2進数の桁-1)になっていることに注目して下さい。例えば100(2進数の3桁)は2^(3-1)=4です。
 この表の数値はコンピュータ関連の文章で、かなり良く目にしていると思います。
 これは、丁度2進数としては「切りが良い」数値だからです。

 2進数の4桁で表せる最大の数値は1111です。桁ごとに分解すると1000+100+10+1ですから、これを10進数に置き変えると、上の表を参考にして8+4+2+1となります。
 これを全て足すと8+4+2+1=15です。
 2進数の4桁の数値で最小のものは0000つまり0、これは10進数でも0です
 結局4桁の2進数では、10進数での0〜15までの数値が表せると言う事になります。

16進数とは

 たかだか0〜15を表すのに4桁も使うのは、人間としては非常に読みにくいデータになり、ミスのもとです。そこで、2進数を4桁で区切って16進数(つまり16で桁が繰り上がり10となる数値)として扱う事にしました。
 ところが、私たちが普段使っているのは10進数で、0123456789の10種類の数字で表されています。これでは、16進数を表すには6つ数字が足りません。
 仕方がないので、さらにアルファベットのABCDEFの6つを加えた0123456789ABCDEFで16進数を表すことにしました。A〜Fは10進数の10〜15に対応しています。
 ちなみに10進数をつかわないのは、2^nでは10は表せない、つまりはコンピュータとしては、「非常に切りが悪い」数値だからです。

2進数01101110010111011110001001101010111100110111011111
10進数0123456789101112131415
16進数0123456789ABCDEF

 例えば2桁の16進数1Fは、桁毎に分けると10+Fと分けられ、それぞれ10進数に変換すると1*16+15=31となります。8AEならば、800+A0+Eであり、10進数に変換すると8*16^2+10*16^1+14*16^0=2222となります。
 256とか1024等の数字を見て「切りが良い」と思えるようになったら、コンピュータプログラマとしてはしめたものです。

10進数24816326412825651210242046409681921638432768
16進数248102040801002004008001000200040008000

10進数→16進数

 16進数はプログラムをする上ではやたらと出てくるものですから、他の言語では16進数を扱う方法が用意されていることが多いのですが、AppleScriptには用意されていません。
 具体的にはHTMLのタグに使う色の指定などに使うことがあると思います。
 無いのならば、しょうがないので自前で変換ルーチンを用意します。再帰呼び出しハンドラですから、慣れていない人にはちょっと分かりにくいかもしれません(再帰呼び出しを使わなくても変換ハンドラを作ることはできます)
 詳しくは「再帰呼び出し」を参照して下さい。

dec2Hex(125)

on dec2Hex(theDEC)
	if theDEC = 0 then return ""
	return dec2Hex(theDEC div 16) & (character ((theDEC mod 16) + 1) of "0123456789ABCDEF")
end dec2Hex

2000-07-01というか、私自身が慣れてなくて、ことをややこしくしてました。
 そんなわけで、dec2Hexハンドラは簡単なものに書き換えました。

16進数→10進数

 以下は、逆に16進数の文字列から、10進数を求めるハンドラです。

hex2Dec("ff") -- 16進の表記は、大文字でも小文字でも構いません。

on hex2Dec(theHEX)
	set theDEC to 0
	repeat with i from 1 to (length of theHEX)
		set theChar to (character -i of theHEX)
		repeat with j from 0 to 15
			if (character (j + 1) of "0123456789ABCDEF") = theChar then exit repeat
		end repeat
		set theDEC to theDEC + j * (16 ^ (i - 1))
	end repeat
	return theDEC -- 最後のresultが返り値になるので、この行は無くても動作します
end hex2Dec
hex2dec("ffff0") -- 文字列はもちろん
hex2dec({"f", "f", "f", "f", "0"}) -- リストでもOKだったりします

on hex2dec(theHEX)
	set theDEC to 0
	repeat with curChar in theHEX
		repeat with i from 0 to 15
			if (character (i + 1) of "0123456789ABCDEF") = (curChar) as string then exit repeat
		end repeat
		set theDEC to theDEC * 16 + i
	end repeat
	return theDEC
end hex2dec

2000-09-04少しばかりパフォーマンスを向上させようと思って書き換えました。リストも使えるようにしました。

16進数⇔10進数

 以上のハンドラを利用して、16進数と10進数を相互変換するスクリプトを作ってみました。
 アプレットにして、アップルメニューに入れておくと、便利かと思います。
 hex2Decとdec2Hexは、先程作ったハンドラです。

set tmp to (display dialog "" default answer "" buttons {"16進数へ", "10進数へ", "キャンセル"})

if button returned of tmp = "10進数へ" then
	display dialog "" default answer hex2dec(text returned of tmp)
else if button returned of tmp = "16進数へ" then
	display dialog "" default answer dec2hex(text returned of tmp)
end if

2000-05-12 -2000-07-27