RosettaCodeData/Task/Negative-base-numbers/Action-/negative-base-numbers.action
2023-07-01 13:44:08 -04:00

81 lines
1.2 KiB
Text

CHAR ARRAY digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!"
INT FUNC MyMod(INT a,b)
IF b>=0 THEN
RETURN (a MOD b)
FI
RETURN (a-(b*(a/b)))
PROC Encode(INT n,base CHAR ARRAY res)
INT i,d,len
CHAR tmp
IF base<-63 OR base>-1 THEN Break() FI
IF n=0 THEN SAssign(res,"0") FI
len=0
WHILE n#0
DO
d=MyMod(n,base)
n==/base
IF d<0 THEN
n==+1
d==-base
FI
len==+1
res(len)=digits(d+1)
OD
res(0)=len
FOR i=1 to len/2
DO
tmp=res(i)
res(i)=res(len-i+1)
res(len-i+1)=tmp
OD
RETURN
BYTE FUNC Index(CHAR ARRAY s CHAR c)
BYTE i
FOR i=1 TO s(0)
DO
IF s(i)=c THEN RETURN (i) FI
OD
RETURN (0)
INT FUNC Decode(CHAR ARRAY s INT base)
INT res,b,i,pos
IF base<-63 OR base>-1 THEN Break() FI
IF s(0)=1 AND s(1)='0 THEN RETURN (0) FI
res=0
b=1
pos=s(0)
WHILE pos>=1
DO
i=Index(digits,s(pos))-1
res==+i*b
b==*base
pos==-1
OD
RETURN (res)
PROC Test(INT n,base)
CHAR ARRAY s(20)
INT v
Encode(n,base,s)
PrintF("%I encoded in base %I is %S%E",n,base,s)
v=Decode(s,base)
PrintF("%S decoded in base %I is %I%E%E",s,base,v)
RETURN
PROC Main()
INT v
Test(10,-2)
Test(146,-3)
Test(15,-10)
Test(-568,-63)
RETURN