72 lines
1.9 KiB
Plaintext
72 lines
1.9 KiB
Plaintext
$ 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;
|