it is a simple "get the remainder after integer division by the base and 'shift' sort of routine"
Take a number like 9 - convert to base two. The first step would be to find the remainder after division by 2 (remainder = 1). That is the first bit. Now "shift" that portion off (trunc(l_num/p_base) does that). We are left with the number 4. What is the remainder of after division by 2 (remainder = 0), that is the second bit. Now shift again (divide by base) and we have l_num=2. Remainder after division = 0, that is the third bit. Shift, we have 1. remainder = 1, that is the fourth bit - we are left with zero. Hence we are done... so
1001 is binary for decimal 9.
Put in some debug and see what it does next time :)
ops$tkyte%ORA9IR2> create or replace function to_base( p_dec in number, p_base in number )
2 return varchar2
3 is
4 l_str varchar2(255) default NULL;
5 l_num number default p_dec;
6 l_hex varchar2(16) default '0123456789ABCDEF';
7 begin
8 if ( p_dec is null or p_base is null )
9 then
10 return null;
11 end if;
12 if ( trunc(p_dec) <> p_dec OR p_dec < 0 ) then
13 raise PROGRAM_ERROR;
14 end if;
15
16
17 dbms_output.put_line( 'inputs: ' );
18 dbms_output.put_line( 'l_hex := "' || l_hex || '"' );
19 dbms_output.put_line( 'p_base:= "' || p_base || '"' );
20 dbms_output.put_line( 'l_num := "' || l_num || '"' );
21 loop
22 dbms_output.put_line
23 ( 'looping, l_num := ' || l_num ||
24 ', mod(l_num,p_base)+1 = ' || (mod(l_num,p_base)+1) ||
25 ', substr(l_hex, mod(l_num,p_base)+1, 1 ) = "' || substr(l_hex, mod(l_num,p_base)+1, 1 ) || '"' ||
26 ', l_str = "' || l_str || '"' );
27 l_str := substr( l_hex, mod(l_num,p_base)+1, 1 ) || l_str;
28 l_num := trunc( l_num/p_base );
29 exit when ( l_num = 0 );
30 end loop;
31
32
33 return l_str;
34 end to_base;
35 /
Function created.
ops$tkyte%ORA9IR2>
ops$tkyte%ORA9IR2> exec dbms_output.put_line( to_base( 9, 2 ) );
inputs:
l_hex := "0123456789ABCDEF"
p_base:= "2"
l_num := "9"
looping, l_num := 9, mod(l_num,p_base)+1 = 2, substr(l_hex, mod(l_num,p_base)+1, 1 ) = "1", l_str = ""
looping, l_num := 4, mod(l_num,p_base)+1 = 1, substr(l_hex, mod(l_num,p_base)+1, 1 ) = "0", l_str = "1"
looping, l_num := 2, mod(l_num,p_base)+1 = 1, substr(l_hex, mod(l_num,p_base)+1, 1 ) = "0", l_str = "01"
looping, l_num := 1, mod(l_num,p_base)+1 = 2, substr(l_hex, mod(l_num,p_base)+1, 1 ) = "1", l_str = "001"
1001
PL/SQL procedure successfully completed.