############################################################################
#
#	File:     convert.icn
#
#	Subject:  Procedures for various conversions
#
#	Author:   Ralph E. Griswold
#
#	Date:     March 19, 1998
#
############################################################################
#
#   This file is in the public domain.
#
############################################################################
#  
#	exbase10(i, j)	converts base-10 integer i to base j.
#  
#	inbase10(s, i)	convert base-i integer s to base 10.
#  
#	radcon(s, i, j)	convert base-i integer s to base j.
#
#  There are several other procedures related to conversion that are
#  not yet part of this module.
#  
############################################################################

procedure exbase10(i, j)	#: convert base 10 to arbitrary base
   local s, d, sign
   static digits

   initial digits := &digits || &lcase || &ucase

   if not(2 <= j <= *digits) then stop("*** base out of range")

   if i = 0 then return 0

   if i < 0 then {
      sign := "-"
      i := -i
      }
   else sign := ""
   s := ""
   while i > 0 do {
      d := i % j
      if d > 9 then d := digits[d + 1]
      s := d || s
      i /:= j
      }

   return sign || s

end

procedure inbase10(s, i)	#: convert arbitrary base to base 10

   if i > 36 then stop("*** base too large for inbase10()")

   if s[1] == "-" then return "-" || integer(i || "r" || s[2:0])
   else return integer(i || "r" || s)

end

procedure radcon(s, i, j)	#: convert between bases

   return exbase10(inbase10(s,i),j)

end
