前回もPL/SQLを使って10進数から2進数に変換する方法と、2進数から10進数に変換するPL/SQLサンプルを紹介しました。
今回は前回とは違う方法を紹介します。
オラクルの標準関数BITANDを使って10進数から2進数に変換する方法と、オラクルの標準関数BIN_TO_NUMを使って2進数から10進数に変換する方法になります。
10進数から2進数に変換するPL/SQLサンプル(BITANDを使用)
BITANDは第1引数と第2引数の値でAND演算を行い、結果を数値(10進数)で返却してくれます。
BITANDを利用して2のべき乗でAND演算を行えば、どこのビットがオン(1)になるかがわかるという仕組みです。
FUNCTION作成
CREATE OR REPLACE FUNCTION DECTOBIN(
iNum IN NUMBER
) RETURN VARCHAR2
IS
i NUMBER(9);
wkBit VARCHAR2(1);
oBinary VARCHAR2(500) := '';
BEGIN
i := 0;
-- 2のべき乗(i)がiNumを超えるまでループ
WHILE POWER(2,i) < iNum LOOP
-- 1桁ずつビットを求める
wkBit := CASE BITAND(iNum,POWER(2,i)) WHEN 0 THEN '0' ELSE '1' END;
oBinary := wkBit || oBinary;
i := i + 1;
END LOOP;
RETURN oBinary;
END;
/
ファンクションが作成されました。
10進数「9」を2進数に変換
SELECT DECTOBIN(9) FROM DUAL; DECTOBIN(9) ------------------------- 1001
10進数「65535」を2進数に変換
SELECT DECTOBIN(65535) FROM DUAL; DECTOBIN(65535) ------------------------- 1111111111111111
2進数から10進数に変換するSQLサンプル(BIN_TO_NUMを使用)
BIN_TO_NUMはオラクルの標準関数でパラメータにビット文字列を渡すと10進数に変換して返却してくれます。
ただ、パラメーターを動的に指定しないといけないので、扱いにくいです。
2進数「1001」を10進数に変換
SELECT BIN_TO_NUM(1,0,0,1) FROM DUAL;
BIN_TO_NUM(1,0,0,1)
-------------------
9
2進数「1111111111111111」を10進数に変換
SELECT BIN_TO_NUM(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1) FROM DUAL;
BIN_TO_NUM(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)
-------------------------------------------
65535
2進数から10進数に変換するPL/SQLサンプル(BIN_TO_NUMを使用/FUNCTION化)
BIN_TO_NUMはパラメーターが動的になっていて扱いにくいので、ファンクション化して扱いやすくしたサンプルです。
FUNCTIONを作成
CREATE OR REPLACE FUNCTION BINTODEC(
iBinary IN VARCHAR2
) RETURN NUMBER
IS
i NUMBER(9);
wkSQL VARCHAR2(32767);
oNumber NUMBER(9);
BEGIN
i := 1;
oNumber := 0;
wkSQL := 'SELECT BIN_TO_NUM(';
-- iがiBinaryの桁数を超えるまでループ
WHILE i <= LENGTH(iBinary) LOOP
-- BIN_TO_NUMのパラメーターを生成
wkSQL := wkSQL || SUBSTR(iBinary,i,1) || ',';
i := i + 1;
END LOOP;
-- 不要なカンマと最後の構文を追加
wkSQL := SUBSTR(wkSQL,1,LENGTH(wkSQL)-1) || ') FROM DUAL';
-- 動的SQLの実行
EXECUTE IMMEDIATE wkSQL INTO oNumber;
RETURN oNumber;
END;
/
ファンクションが作成されました。
10進数「9」を2進数に変換
SELECT BINTODEC('1001') FROM DUAL;
BINTODEC('1001')
----------------
9
10進数「65535」を2進数に変換
SELECT BINTODEC('1111111111111111') FROM DUAL;
BINTODEC('1111111111111111')
----------------------------
65535
2進数から10進数変換、10進数から2進数変換は色々な実装方法がありますね。
それぞれの処理速度が気になるので次回は検証を行ってみたいと思います。
以上です。