numBinTable num bin --- ---- 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111 8 1000 numBinTableから、 2レコード選ぶ、全ての組み合わせの ビットでの、AND,OR,XORを求める 出力結果 num bin num bin BitAND BitOR BitXOR --- ---- --- ---- ------ ----- ------ 0 0000 0 0000 0000 0000 0000 0 0000 1 0001 0000 0001 0001 0 0000 2 0010 0000 0010 0010 0 0000 3 0011 0000 0011 0011 0 0000 4 0100 0000 0100 0100 0 0000 5 0101 0000 0101 0101 0 0000 6 0110 0000 0110 0110 0 0000 7 0111 0000 0111 0111 0 0000 8 1000 0000 1000 1000 1 0001 1 0001 0001 0001 0000 1 0001 2 0010 0000 0011 0011 1 0001 3 0011 0001 0011 0010 1 0001 4 0100 0000 0101 0101 1 0001 5 0101 0001 0101 0100
create table numBinTable as select 0 as num,'0000' as bin from dual union select 1,'0001' from dual union select 2,'0010' from dual union select 3,'0011' from dual union select 4,'0100' from dual union select 5,'0101' from dual union select 6,'0110' from dual union select 7,'0111' from dual union select 8,'1000' from dual; create or replace function to_base( p_dec in number, p_base in number ) return varchar2 is l_str varchar2(255) default NULL; l_num number default p_dec; l_hex varchar2(50) default '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; begin if ( trunc(p_dec) <> p_dec OR p_dec < 0 ) then raise PROGRAM_ERROR; end if; loop l_str := substr( l_hex, mod(l_num,p_base)+1, 1 ) || l_str; l_num := trunc( l_num/p_base ); exit when ( l_num = 0 ); end loop; return l_str; end to_base; /
col anum for 999 col bnum for 999 col BitAND for a6 col BitOR for a6 col BitXOR for a6 --■■■UTL_RAWパッケージを使わない方法■■■ select a.num as anum,a.bin, b.num as bnum,b.bin, LPad(to_base(bitand(a.num,b.num),2),4,'0') as "BitAND", LPad(to_base(a.num+b.num-bitand(a.num,b.num),2),4,'0') as "BitOR", LPad(to_base(a.num+b.num-2*bitand(a.num,b.num),2),4,'0') as "BitXOR" from numBinTable a,numBinTable b where a.num <= b.num; --■■■UTL_RAWパッケージを使う方法■■■ select a.num as anum,a.bin, b.num as bnum,b.bin, LPad(to_base(bitand(a.num,b.num),2),4,'0') as "BitAND", LPad(to_base( utl_raw.cast_to_binary_integer( utl_raw.bit_or( utl_raw.cast_from_binary_integer(a.num), utl_raw.cast_from_binary_integer(b.num))) ,2),4,'0') as "BitOR", LPad(to_base( utl_raw.cast_to_binary_integer( utl_raw.bit_xor( utl_raw.cast_from_binary_integer(a.num), utl_raw.cast_from_binary_integer(b.num))) ,2),4,'0') as "BitXOR" from numBinTable a,numBinTable b where a.num <= b.num;
ビットORは、 ビット加算 - ビットAnd で求めることができます 場合に分けて証明すると ■■■■■■■■■■■■■■■■■■ 場合1 0と0の場合 ビット加算 ビットAnd ビットOR 0 0 0 + 0 BitAnd 0 BitOR 0 --- -------- -------- 0 0 0 ビットOR = 0 ビット加算 - ビットAnd = 0 - 0 = 0 なので ビットOR = ビット加算 - ビットAnd は、成り立つ ■■■■■■■■■■■■■■■■■■ 場合2 0と1の場合(交換法則より、1と0の場合も含む) ビット加算 ビットAnd ビットOR 0 0 0 + 1 BitAnd 1 BitOR 1 --- -------- -------- 1 0 1 ビットOR = 1 ビット加算 - ビットAnd = 1 - 0 = 1 なので ビットOR = ビット加算 - ビットAnd は、成り立つ ■■■■■■■■■■■■■■■■■■ 場合3 1と1の場合 ビット加算 ビットAnd ビットOR 1 1 1 + 1 BitAnd 1 BitOR 1 --- -------- -------- 10 1 1 ビットOR = 1 ビット加算 - ビットAnd = 10 - 1 = 1 なので ビットOR = ビット加算 - ビットAnd は、成り立つ ■■■■■■■■■■■■■■■■■■ 以上により、 ビットOR = ビット加算 - ビットAnd が成り立ちます。 ビット加算で、繰り上がりが発生したとしても ビットAndを引いているので、繰り下がりが発生して、 結果として、上位桁への繰り上がりが、発生しないのです
ビットXORは、 ビットOR - ビットAND で求めることができます 場合に分けて証明すると ■■■■■■■■■■■■■■■■■■ 場合1 0と0の場合 ビットOR ビットAnd ビットXOR 0 0 0 BitOR 0 BitAnd 0 BitXOR 0 -------- -------- --------- 0 0 0 ビットXOR = 0 ビットOR - ビットAND = 0 - 0 = 0 なので ビットXOR = ビットOR - ビットAND は、成り立つ ■■■■■■■■■■■■■■■■■■ 場合2 0と1の場合(交換法則より、1と0の場合も含む) ビットOR ビットAnd ビットXOR 0 0 0 BitOR 1 BitAnd 1 BitXOR 1 -------- -------- --------- 1 0 1 ビットXOR = 1 ビットOR - ビットAND = 1 - 0 = 0 なので ビットXOR = ビットOR - ビットAND は、成り立つ ■■■■■■■■■■■■■■■■■■ 場合3 1と1の場合 ビットOR ビットAnd ビットXOR 1 1 1 BitOR 1 BitAnd 1 BitXOR 1 -------- -------- --------- 1 1 0 ビットXOR = 0 ビットOR - ビットAND = 0 - 0 = 0 ■■■■■■■■■■■■■■■■■■ 以上により、 ビットXOR = ビットOR - ビットAND が成り立ちます。 8-20 集合関数のBitAND,BitOR,BitXOR 10-163 ビット演算(NOT)