#!/bin/ksh # to_base n m # Convert n from decimal to base m # # William Robertson - www.williamrobertson.net # Originally a prototype for equivalent function in PL/SQL when no database was available. # Since writing this I have discovered the extended typeset -i syntax, so most of this could # actually be achieved by: # typeset -i$2 v_result=$1 if (( $# != 2 )); then # Two parameters required, else return error and usage message: print -u2 "$0: Usage: to_base n m\nConverts n from decimal to base n" exit 1 fi # Easy way using subsequently discovered typeset built-in: typeset -i${2} v_result_string=$1 # print ${v_result_string#*#} # The Hard Way: typeset -i p_decimal=$1 v_decimal_remaining=$1 p_base=${2:-10} v_digit if (( p_base > 36 )) then print -u2 $0: Maximum base is 36 exit 1 fi function to_single_digit { typeset -i v_decimal=$1 if (( v_decimal < 10 )); then v_result=${v_decimal} else case ${v_decimal} in 10 ) v_result=A ;; 11 ) v_result=B ;; 12 ) v_result=C ;; 13 ) v_result=D ;; 14 ) v_result=E ;; 15 ) v_result=F ;; 16 ) v_result=G ;; 17 ) v_result=H ;; 18 ) v_result=I ;; 19 ) v_result=J ;; 20 ) v_result=K ;; 21 ) v_result=L ;; 22 ) v_result=M ;; 23 ) v_result=N ;; 24 ) v_result=O ;; 25 ) v_result=P ;; 26 ) v_result=Q ;; 27 ) v_result=R ;; 28 ) v_result=S ;; 29 ) v_result=T ;; 30 ) v_result=U ;; 31 ) v_result=V ;; 32 ) v_result=W ;; 33 ) v_result=X ;; 34 ) v_result=Y ;; 35 ) v_result=Z ;; * ) print -u2 Digit ${v_decimal} too large; exit 1 ;; esac fi print ${v_result} } while (( v_decimal_remaining > 0 )) do (( v_digit = v_decimal_remaining % p_base )) v_result=$(to_single_digit ${v_digit} )${v_result} (( v_decimal_remaining = v_decimal_remaining / p_base )) done # Self-diagnostic: ksh can convert base n to decimal using syntax n#value, e.g. # print $(( 16#f )) # 15 # so we can check results by converting back. This can be skipped unless decimal # is over around 10**31 (pdksh on Apple Mac hits a limit and returns empty string). if (( p_decimal = $(( ${p_base}#${v_result} )) )) then print ${v_result} else print -u2 "ERROR: result '${v_result}' is incorrect" exit 2 fi