context: /*
   * Created by SharpDevelop.
   * User: 	rob tillaart
   * Date: 	29/09/2005
   * Time: 	19:18
   * Version:	1.00
   * 
   * Modified by Ali Adams
   * www.heliwave.com
   */
  using System;
  
  public class Radix
  {
      // CAPITAL LETTERS for digit symbols. Small letters are for Math functions and constants
      public static string DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  
      static string ErrRadixTooLarge1 = "RadixError: radix larger than 36.";
      static string ErrRadixTooLarge2 = "RadixError: radix larger than 1000000.";
      static string ErrRadixTooSmall = "RadixError: radix smaller than 2.";
      static string ErrRadixFormat = "RadixError: number not in radix format.";
      static string ErrRadixDecode = "RadixError: generic decode error.";
      static string ErrRadixNoSymbolFormat = "RadixError: number not in symbolic_display format.";
  
      public static string Spaces(string value, int number)
      {
          return Spaces(value, number, ' ');
      }
      public static string Spaces(string value, int number, char separator)
      {
          string result = null;
          int j = 0;
          for (int i = value.Length - 1; i >= 0; i--)
          {
              j++;
              result = value[i] + result;
              if (j % number == 0) result = separator + result;
          }
          if (result[0] == separator) result = result.Substring(1);
          return result;
      }
      private static void CheckArg(long radix, bool symbolic_display)
      {
          if ((radix > 36) && (!symbolic_display))
          {
              throw new Exception(ErrRadixTooLarge1);
          }
          if (radix > 1000000)
          {
              throw new Exception(ErrRadixTooLarge2);
          }
          if (radix < 2)
          {
              throw new Exception(ErrRadixTooSmall);
          }
      }
  
      public static string Encode(long value, int radix)
      {
          return Encode(value, radix, false);
      }
      public static string Encode(long value, int radix, bool symbolic_display)
      {
          // check parameters
          CheckArg(radix, symbolic_display);
  
          // work in positive domain
          long t = Math.Abs(value);
  
          // return value
          string result = null;
  
          if (symbolic_display)
          {
              if (t == 0L)
              {
                  result = ",0";
              }
              while (t > 0L)
              {
                  // split of one digit
                  long r = t % radix;
                  // convert it and add it to the return string
                  result = "," + r.ToString() + result;
                  t = (t - r) / radix;
              }
              result = result.Substring(1);			// strip one ','
              // add sign
              if (value < 0L)
              {
                  result = "-," + result;
              }
              if (value == 0L)
              {
                  result = "0";
              }
              result = "[(" + radix + ")," + result + "]";
          }
          else
          {
              if (t == 0L)
              {
                  result = "0";
              }
              while (t > 0L)
              {
                  // split of one digit
                  long r = t % radix;
                  // convert it and add it to the return string
                  result = DIGITS[(int)r] + result;
                  t = (t - r) / radix;
              }
              if (value < 0L)
              {
                  // add sign
                  result = "-" + result;
              }
              if (value == 0L)
              {
                  result = "0";
              }
          }
          return result;
      }
      public static long Decode(string value, int radix)
      {
          return Decode(value, radix, false);
      }
      public static long Decode(string value, int radix, bool symbolic_display)
      {
          if (String.IsNullOrEmpty(value)) return 0L;
          CheckArg(radix, symbolic_display);
  
          long result = 0L;
          try
          {
              if (symbolic_display)
              {
                  string ws = value.Trim();
                  if (ws[0] != '[')
                  {
                      throw new Exception(ErrRadixNoSymbolFormat);
                  }
                  // strip [(
                  ws = ws.Substring(2);
                  // get radix
                  int pos = ws.IndexOf(')');
                  if (pos > -1)
                  {
                      long tr = Int64.Parse(ws.Substring(0, pos));
                      // strip it
                      ws = ws.Substring(pos + 2);
                      ws = ws.Remove(ws.Length - 1, 1);		// strip ]
  
                      char sign = ws[0];
                      int si = 1;
                      if ((sign == '-') || (sign == '+'))
                      {
                          if (sign == '-') si = -1;
                          ws = ws.Substring(2);				// skip sign and ,
                      }
  
                      string[] t = ws.Split(',');
                      for (int i = 0; i < t.Length; i++)
                      {
                          result *= radix;
                          long l = long.Parse(t[i]);
                          if ((l < 0) || (l >= radix)) throw new Exception(ErrRadixFormat);
                          result += l;
                      }
                      // add sign
                      result *= si;
                  }
              }
              else
              {
                  string ws = value.Trim();
                  char sign = ws[0];
                  int si = 1;
                  if ((sign == '-') || (sign == '+'))
                  {
                      if (sign == '-') si = -1;
                      ws = ws.Substring(1);
                  }
  
                  for (int i = 0; i < ws.Length; i++)
                  {
                      result *= radix;
                      char c = ws[i];
                      long l = DIGITS.IndexOf(c);
                      if ((l < 0) || (l >= radix)) throw new Exception(ErrRadixFormat);
                      result += l;
                  }
                  // add sign
                  result *= si;
              }
          }
          catch
          {
              throw new Exception(ErrRadixDecode);
          }
  
          return result;
      }
  
      public static string Encode(double value, int radix)
      {
          return Encode(value, radix, false);
      }
      public static string Encode(double value, int radix, bool symbolic_display)
      {
          CheckArg(radix, symbolic_display);
  
          double t = Math.Abs(value);
  
          // first part before decimal point
          long t1 = (long)t;
  
          // t2 holds part after decimal point
          double t2 = t - t1;
  
          // return value;
          string result = null;
  
          if (symbolic_display)
          {
              if (value == 0.0D)
              {
                  result = ",0";
              }
              // process part before decimal point
              while (t1 > 0L)
              {
                  long r = t1 % radix;
                  result = "," + r.ToString() + result;
                  t1 = (t1 - r) / radix;
              }
              result = result.Substring(1);	// strip one ','
  
              // after the decimal point
              if (t2 > 0.0D)
              {
                  result += ",.,";
              }
              int maxdigit = 50; // to prevent endless loop
              while (t2 > 0.0D)
              {
                  long r = (long)Math.Round((t2 * radix));
                  result += r.ToString() + ",";
                  t2 = (t2 * radix) - r;
  
                  // forced break after maxdigits
                  maxdigit--;
                  if (maxdigit == 0) break;
              }
              result = result.Substring(0, result.Length - 1);	// strip one ','
              if (value < 0.0D)
              {
                  result = "-," + result;
              }
              result = "[(" + radix + ")," + result + "]";
          }
          else
          {
              if (value == 0.0D)
              {
                  result = "0";
              }
              // process part before decimal point
              while (t1 > 0L)
              {
                  long r = t1 % radix;
                  result = DIGITS[(int)r] + result;
                  t1 = (t1 - r) / radix;
              }
  
              // after the decimal point
              if (t2 > 0.0D)
              {
                  result += ".";
              }
              int maxdigit = 50; // to prevent endless loop
              while (t2 > 0.0D)
              {
                  long r = (long)Math.Round((t2 * radix));
                  result += DIGITS[(int)r];
                  t2 = (t2 * radix) - r;
  
                  // forced break after 10 digits
                  maxdigit--;
                  if (maxdigit == 0) break;
              }
              if (value < 0.0D)
              {
                  result = "-" + result;
              }
          }
          return result;
      }
      public static void Decode(string value, int radix, out double result)
      {
          Decode(value, radix, out result, false);
      }
      public static void Decode(string value, int radix, out double result, bool symbolic_display)
      {
          result = 0.0D; // out param must be filled before return
          if (String.IsNullOrEmpty(value)) return;
          CheckArg(radix, symbolic_display);
  
          try
          {
              double tradix = 1.0D;
              if (symbolic_display)
              {
                  string ws = value.Trim();
                  // strip [(
                  ws = ws.Substring(2);
                  // get radix
                  int pos = ws.IndexOf(')');
                  if (pos > -1)
                  {
                      long tr = Int64.Parse(ws.Substring(0, pos));
                      // strip it
                      ws = ws.Substring(pos + 2);
                      ws = ws.Remove(ws.Length - 1, 1);		// strip ]
  
                      char sign = ws[0];
                      int si = 1;
                      if ((sign == '-') || (sign == '+'))
                      {
                          if (sign == '-') si = -1;
                          ws = ws.Substring(2);					// skip sign and ,
                      }
  
                      string[] t = ws.Split(',');
                      bool before = true;
                      for (int i = 0; i < t.Length; i++)
                      {
                          if (t[i] == ".")
                          {
                              before = false;
                              continue;
                          }
                          // next 'digit'
                          long l = long.Parse(t[i]);
                          if ((l < 0L) || (l >= radix)) throw new Exception(ErrRadixFormat);
  
                          if (before)
                          {
                              // process before dec. point
                              result *= radix;
                              result += l;
                          }
                          else
                          {
                              // process after decimal point
                              tradix *= radix;
                              result += l / tradix;
                          }
                      }
  
                      // add sign
                      result *= si;
                  }
              }
              else
              {
                  string ws = value.Trim();
                  char sign = ws[0];
                  int si = 1;
                  if ((sign == '-') || (sign == '+'))
                  {
                      if (sign == '-') si = -1;
                      ws = ws.Substring(1);
                  }
  
                  bool before = true;
  
gt:                 for (int i = 0; i < ws.Length; i++)