$ 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;