utl_raw.bit_and attaches extra 0 after and operation in oracle sql
That is not handled as binary, but hexadecimal.

select
          length( '0100000000000000000000000000000') as l_a_in_chars,
  utl_raw.length( '0100000000000000000000000000000') as l_a_in_bytes,
          length( '1111111111111100000000000000011') as l_b_in_chars,
  utl_raw.length( '1111111111111100000000000000011') as l_b_n_bytes,
          length('00100000000000000000000000000000') as l_ab_in_chars,
  utl_raw.length('00100000000000000000000000000000') as l_ab_in_bytes
from dual;

L_A_IN_CHARS L_A_IN_BYTES L_B_IN_CHARS L_B_N_BYTES L_AB_IN_CHARS L_AB_IN_BYTES
------------ ------------ ------------ ----------- ------------- -------------
          31           16           31          16            32            16


It is not the length in characters that matters, but the length in bytes, and that was the same the whole time. You can not have hexadecimal with odd number of characters. It is not the output that has an extra 0 attached, but your input, on the automatic conversion from hex to raw:

select hextoraw('0100000000000000000000000000000') from dual;

HEXTORAW('0100000000000000000000
--------------------------------
00100000000000000000000000000000


Your input does not fit into RAW(15), requires RAW(16) where the required 0-s are added as required, and there is no such thing as RAW(15.5):

SQL&gt; select cast ('0100000000000000000000000000000' as raw(16)) from dual;

CAST('01000000000000000000000000
--------------------------------
00100000000000000000000000000000

SQL&gt; select cast ('0100000000000000000000000000000' as raw(15)) from dual;
select cast ('0100000000000000000000000000000' as raw(15)) from dual
             *
ERROR at line 1:
ORA-25137: Data value out of range


Since you seem to store your numbers as strings, you can quite easily check the position of 1 "bit":

SQL&gt; select substr('1111111111111100000000000000011', -30, 1) from dual;

S
-
1