Negative base numbers are an alternate way to encode numbers without the need for a minus sign. Various negative bases may be used including negadecimal (base -10), negabinary (-2) and negaternary (-3).[1][2]



Task

Encode the decimal number 10 as negabinary (expect 11110)
Encode the decimal number 146 as negaternary (expect 21102)
Encode the decimal number 15 as negadecimal (expect 195)
In each of the above cases, convert the encoded number back to decimal.


extra credit

 supply an integer, that when encoded to base   -62   (or something "higher"),   expresses the 
name of the language being used   (with correct capitalization).   If the computer language has 
non-alphanumeric characters,   try to encode them into the negatory numerals,   or use other 
characters instead.


$ include "seed7_05.s7i";
 
const string: DIGITS is "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
const func string: encodeNegativeBase (in var integer: number, in integer: base) is func
  result
    var string: encoded is "";
  local
    var integer: remainder is 0;
  begin
    if base < -62 or base > -1 then
      raise RANGE_ERROR;
    elsif number = 0 then
      encoded := "0";
    else
      while number <> 0 do
        remainder := number rem base;
        number := number div base;
        if remainder < 0 then
          incr(number);
          remainder -:= base;
        end if;
        encoded &:= DIGITS[succ(remainder)];
      end while;
      encoded := reverse(encoded);
    end if;
  end func;
 
const func integer: decodeNegativeBase (in string: encoded, in integer: base) is func
  result
    var integer: decoded is 0;
  local
    var integer: factor is 1;
    var integer: index is 0;
    var integer: digit is 0;
  begin
    if base < -62 or base > -1 then
      raise RANGE_ERROR;
    elsif encoded = "0" then
      decoded := 0;
    else
      for index range length(encoded) downto 1 do
        digit := pred(pos(DIGITS, encoded[index]));
        if digit = -1 then
          raise RANGE_ERROR;
        else
          decoded +:= digit * factor;
          factor *:= base;
        end if;
      end for;
    end if;
  end func;
 
const proc: doCheck (in integer: number, in integer: base) is func
  local
    var string: encoded is "";
    var integer: decoded is 0;
  begin
    encoded := encodeNegativeBase(number, base);
    writeln(number lpad 10 <& " encoded in base " <& base lpad 3 <& " = " <& encoded);
    decoded := decodeNegativeBase(encoded, base);
    writeln(encoded lpad 10 <& " decoded in base " <& base lpad 3 <& " = " <& decoded);
  end func;
 
const proc: main is func
  begin
    doCheck(10, -2);
    doCheck(146, -3);
    doCheck(15, -10);
    doCheck(404355637, -62);
  end func;