【IRIS/Cache】進数のすゝめ

今回の記事は、進数計算について解説します。

※この記事は下記の方向けになります。
  • 進数計算を行いたい方
  • 電卓を出すより前に、思わずIRIS/Cacheターミナルを起動する


はじめに

進数計算は、コンピュータやプログラミングを学ぶ際に、ちょいちょい出てくる基礎知識です。
本記事では、進数計算の基本を解説し、ObjectScriptでの利用方法について紹介します。

進数計算に初めて触れる初心者の方でも理解できるよう、わかりやすく整理しました。
本記事を読み進めることで、進数の基礎からObjectScriptを使った実践的な計算方法まで学ぶことができます。

さっそく、進数計算の基本からみていきましょう。

進数計算をする方法

進数計算とは、数値を特定の基数で表現し演算する方法です。
私たちが日常で使う10進数ですが、コンピュータでは2進数や16進数がよく使用されます。

2進数は「1」と「0」の2種類の数値のみで表現し、16進数は「0~9」の数字と「A~F」のアルファベットの計16種類の文字を組み合わせて表現します。

16進数への変換方法

ObjectScriptのコマンドを使用し、10進数から16進数への変換には、下記2通りの方法があります。

s dec = 255

// $zHexコマンドを実行
w $zHex(dec) // → FFと表示

// %SYSTEM.Utilクラスを利用
w $system.Util.DecimalToHex(dec) // → FFと表示

16進から10進数への変換方法

16進数から10進数への変換方法も2通りあります。
また、$zHexは一つのコマンドで「10進数←→16進数」を変換するため、16進数の「数値のみ」の場合は、要注意です。

s hex = "FF"

// $zHexコマンドを実行
w $zHex(hex) // → 255と表示

// %SYSTEM.Utilクラスを利用
w $system.Util.HexToDecimal(hex) // → 255と表示

// 小文字もOK
s hex = "ff"
w $zHex(hex) // → 255と表示
w $system.Util.HexToDecimal(hex) // → 255と表示


//---------------------------------------
// 16進数の数値のみの場合
s hex = 255

// G以降のアルファベットを付与して文字列にする
w $zHex(hex_"Z") // → 597と表示
// 数値を文字列として扱う
w $zHex(""_hex_"") // → 597と表示


//---------------------------------------
// 数値と文字列の動作確認
s hex = "255"
w $zHex(hex) // → 597と表示
w $zHex(+hex) // → FFと表示

$zHexを実行する際は、引数が「文字列 or 数値」を確認しないと不具合の元になる

イレギュラーケース

$zHexと$SYSTEM.Utilクラスはイレギュラーな値の場合、挙動が異なるため要注意です。

s hex = "HH"
w $zHex(hex) // → 0と表示
w $system.Util.HexToDecimal(hex) // <ILLEGAL VALUE>エラーとなる

s hex = ""
w $zHex(hex) // → <FUNCTION>エラーとなる
w $system.Util.HexToDecimal(hex) // → nullと表示

s dec = 1.1
w $zHex(dec) // → <FUNCTION>エラーとなる
w $system.Util.DecimalToHex(dec) // → <ILLEGAL VALUE>エラーとなる
w $system.Util.HexToDecimal(dec) // → <ILLEGAL VALUE>エラーとなる

■16進数以外の文字列
$zHexは0を出力し、%SYSTEM.Utilクラスはエラーとなる

■nullの場合
$zHexはエラーとなり、%SYSTEM.Utilクラスはnullを出力する

■小数点
両コマンドともエラーとなる。エラー内容は異なる。

2進数や8進数への変換について

ObjectScriptには10進数を16進数に変換するコマンドはありますが、他の進数に変換するコマンドは存在しません。

そのため、変換が必用であれば、変換関数を自作する必要があります。

10進数から2進数への変換方法

サンプルです。
引数「num」の値を、求める進数で割った余りを戻り値「bny」の先頭に付け、割った値を次のループで使用しています。

ClassMethod cnvBinary(num As %Integer, hex As %Integer = 2) As %String
{
	q:num=0 0
	s bny = ""
	f {
		s bny = (num # hex)_bny  // 商の余りを先頭に付与
		, num = num \ hex // 商を取得
		q:(num<=0)
	}
	q bny
}

コマンドは下記になります。

w ##class(developer.Sample).cnvBinary(10) // 2進数変換 1010と表示
w ##class(developer.Sample).cnvBinary(10,8) // 8進数変換 12と表示

2進数から10進数への変換

サンプルです
文字を一文字つづ取得し、各桁数に沿って「べき乗」を行い、引数「dec」に加算していきます。

ClassMethod cnvDecimal(num As %String, hex As %Integer = 2) As %Integer
{
	s dec = 0
	, len = $l(num) // 文字数
	f pos=1:1:len {
		// 各桁毎に計算を行う
		s dec = dec + ($e(num, pos) * (hex ** (len - pos)))
	}
	q dec
}

コマンドは下記になります。

w ##class(developer.Sample).cnvDecimal(1010) // 2進数>10進数変換 10と表示
w ##class(developer.Sample).cnvDecimal(12,8) // 8進数>10進数変換 10と表示

ターミナル実行用

ターミナルで気軽に実行できるように、ペーストできるように調整しました。
このままコピーして貼り付けてください。

ターミナルへのペースト関連を詳細に知りたい方は下記記事を参照してください。

10進数から2進数へ変換

cnvBinary(num,hex)	;
	q:num=0 0
	s bny = ""
	f {
		s bny = (num # hex)_bny
		, num = num \ hex
		q:(num<=0)
	}
	q bny

実行コマンドは下記になります。

w $$cnvBinary(10,2) // → 1010と出力される

2進数から10進数への変換

cnvDecimal(num,hex)	;
	s dec = 0
	, len = $l(num)
	f pos=1:1:len {
		s dec = dec + ($e(num, pos) * (hex ** (len - pos)))
	}
	q dec

実行コマンドは下記になります。

w $$cnvDecimal(1010,2) // → 10と出力される

おわりに

本記事では、進数計算の基本とObjectScriptでの具体的な操作方法をご紹介しました。

進数計算を理解することで、プログラミングやデータ処理の効率を高められます。
進数計算をマスターすれば、プログラミングの幅がちょっとだけ広がると思います。

ぜひ本記事で学んだ内容を実践し、ObjectScriptのスキル向上に役立ててください。