トップページに戻る    次のSQLパズルへ    前のSQLパズルへ

2-1-9 数値を2進数、16進数に変換

SQLパズル

数値を、2進数、16進数に変換する。


SQL

col  "2進数" for a20
col "16進数" for a10

--■■■bitand関数を使う方法■■■
select val as "10進数",
to_char(sign(bitand(val,power(2, 8-1)))) ||
to_char(sign(bitand(val,power(2, 7-1)))) ||
to_char(sign(bitand(val,power(2, 6-1)))) ||
to_char(sign(bitand(val,power(2, 5-1)))) ||
to_char(sign(bitand(val,power(2, 4-1)))) ||
to_char(sign(bitand(val,power(2, 3-1)))) ||
to_char(sign(bitand(val,power(2, 2-1)))) ||
to_char(sign(bitand(val,power(2, 1-1)))) as "2進数",
to_char(val,'XX') as "16進数"
from (select 255 as val from dual union select 200 from dual union select 129 from dual
union select 128 from dual union select 127 from dual union select 2 from dual
union select   1 from dual union select   0 from dual)
order by val desc;

--■■■Replace関数を使う方法■■■
select val as "10進数",
LPad(LTrim(translate(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(
Replace(Replace(Replace(Replace(Replace(Replace(Replace(to_char(val,'XX')
,'0','----')
,'1','---+')
,'2','--+-')
,'3','--++')
,'4','-+--')
,'5','-+-+')
,'6','-++-')
,'7','-+++')
,'8','+---')
,'9','+--+')
,'A','+-+-')
,'B','+-++')
,'C','++--')
,'D','++-+')
,'E','+++-')
,'F','++++'),'+-','10')),8,'0') as "2進数",
to_char(val,'XX') as "16進数"
from (select 255 as val from dual union select 200 from dual union select 129 from dual
union select 128 from dual union select 127 from dual union select 2 from dual
union select   1 from dual union select   0 from dual)
order by val desc;

--■■■情報処理技術者試験で使われる方法■■■
select val as "10進数",
to_char(mod(trunc(val/power(2,7)),2)) ||
to_char(mod(trunc(val/power(2,6)),2)) ||
to_char(mod(trunc(val/power(2,5)),2)) ||
to_char(mod(trunc(val/power(2,4)),2)) ||
to_char(mod(trunc(val/power(2,3)),2)) ||
to_char(mod(trunc(val/power(2,2)),2)) ||
to_char(mod(trunc(val/power(2,1)),2)) ||
to_char(mod(val,2)) as "2進数",
to_char(val,'XX') as "16進数"
from (select 255 as val from dual union select 200 from dual union select 129 from dual
union select 128 from dual union select 127 from dual union select 2 from dual
union select   1 from dual union select   0 from dual)
order by val desc;

--■■■情報処理技術者試験で使われる方法(小数も対応)■■■
select val as "10進数",
to_char(mod(trunc(整数部/power(2,7)),2)) ||
to_char(mod(trunc(整数部/power(2,6)),2)) ||
to_char(mod(trunc(整数部/power(2,5)),2)) ||
to_char(mod(trunc(整数部/power(2,4)),2)) ||
to_char(mod(trunc(整数部/power(2,3)),2)) ||
to_char(mod(trunc(整数部/power(2,2)),2)) ||
to_char(mod(trunc(整数部/power(2,1)),2)) ||
to_char(mod(整数部,2)) || '.' ||
trunc(小数部*2) ||
trunc(mod(小数部*power(2,1),1)*2) ||
trunc(mod(小数部*power(2,2),1)*2) ||
trunc(mod(小数部*power(2,3),1)*2) ||
trunc(mod(小数部*power(2,4),1)*2) ||
trunc(mod(小数部*power(2,5),1)*2) ||
trunc(mod(小数部*power(2,6),1)*2) ||
trunc(mod(小数部*power(2,7),1)*2) as "2進数"
from (select Val,
             trunc(Val) as 整数部,
             mod(Val,1) as 小数部
       from (select 0.5 as Val from dual
       union all select 0  from dual
       union all select 0.125  from dual
       union all select 0.375  from dual
       union all select 0.25   from dual
       union all select 8.25   from dual
       union all select 16.25  from dual
       union all select 32.1   from dual));


解説

bitand関数を使う方法では、
ビット演算と、sign関数で、ビットが立っているかを調べて、
2進数に変換してます。

16進数に変換する方法は、to_char関数と16進表記の数値書式を使ってます。

ちなみに、
2進数を10進数に変換するには、Bin_To_Num関数を使います。
16進数を10進数に変換するには、UTL_RAW.CAST_TO_BINARY_INTEGERかto_number関数を使います。

マニュアル(BIN_TO_NUM)
マニュアル(BIN_TO_NUM)BIN_TO_NUM(英語)

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
UTL_RAW.CAST_TO_BINARY_INTEGERで16進を10進に変換

select "16進数",UTL_RAW.CAST_TO_BINARY_INTEGER(HEXTORAW("16進数")) as "10進数"
  from (select '10' as "16進数" from dual
  union select '20' from dual);

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
to_number関数で16進を10進に変換

select to_number('100','xxx') from dual;

desc sys.standard
によると、この型定義に該当すると思われます。

FUNCTION TO_NUMBER RETURNS NUMBER
 引数名                         タイプ                  In/Out Default?
 ------------------------------ ----------------------- ------ --------
 LEFT                           VARCHAR2                IN
 FORMAT                         VARCHAR2                IN

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
10進を16進に変換

select to_char(100,'xxx') from dual;

desc sys.standard
によると、この型定義に該当すると思われます。

FUNCTION TO_CHAR RETURNS VARCHAR2
 引数名                         タイプ                  In/Out Default?
 ------------------------------ ----------------------- ------ --------
 LEFT                           NUMBER                  IN
 RIGHT                          VARCHAR2                IN

マニュアル(16進表記の数値書式)(英語)
マニュアル(16進表記の数値書式)

@IT 情報処理技術者試験で使われる方法

OTN-Japan 10進数を2進数に変換

Oracle ACEのTom Kyteさんのto_base関数の使用例
10-163 ビット演算(NOT)