(02-03-2017 01:51 PM)Jan_D Wrote: I slightly modified your program, not because it is not good enough but to make it better readable.
Instead of a CAS variable like tmp586605323013 it uses the CAS variable tmp.
It is also possible to make the program completely local, without using a global CAS variable
tmp, and still do the calculations in CAS.
We can declare a local variable
tmp, and the program will work with this local variable and use it for CAS calculations.
The only thing we have to pay attention to is that it is not allowed to use square brackets, but we have to use parentheses.
So instead of CAS("tmp[1]:=tmp[1]+d*b1^k") we have to write CAS("tmp(1):=tmp(1)+d*b1^k").
Instead of CAS("tmp(1):=tmp(1)+d*b1^k") we could also write: tmp(1):=CAS(“tmp(1)+d*b1^k").
Code:
EXPORT basecalc4()
BEGIN
local maxdigits:=20; // maximum number of digits for frac part
local j,k,t,run:=1;
local b1:=10;
local b2:=16;
local d:=0;
local n:="";
local ds:="";
local ipn:=""; // integer part of n
local fpn:=""; // frac part of n
local digits:="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
local tmp;
while run do
t:=input(
{
{ n, [2], { 15, 80, 0 } },
{ b1, [0], { 25, 25, 1 } },
{ b2, [0], { 70, 25, 1 } },
{ maxdigits, [0], {25,25, 2 } }
},
"Base Converter",
{ "n=", "base1=", "base2=", "digits=" },
{
"Enter the integer",
"Enter the base of the integer n",
"Enter the base to convert to",
"Max allowable digits"
}
);
if t then //when pressed the OK menu key.
CAS("tmp:={0,0}"); //creation of global CAS variable with name tmp
k:=size(n);
if (k AND (b1 >= 2) AND (b2 <= 62)) then
j:=instring(n,".");
if j then
if (j-1>0) then ipn:=left(n,j-1); end;
if (k-j>0) then fpn:=right(n,k-j); end;
k:=j-2;
else
ipn:=n;
k:=size(n)-1;
end;
// k = largest exponent
//conversion of ipn to decimal form and storing it into tmp[1]:
t:=size(ipn);
for j from 1 to t do
ds:=mid(ipn,j,1);
d:=instring(digits,ds)-1;
if ((d >= b1) OR (d < 0)) then msgbox("Invalid digit: " + ds); j:=-1; break; end;
CAS("tmp(1):=tmp(1)+d*b1^k");
k:=k-1;
end;
if (j == -1) then continue; end;
//k=-1 now!
//conversion of fpn to decimal form and storing it into tmp[2]:
t:=size(fpn);
for j from 1 to t do
ds:=mid(fpn,j,1);
d:=instring(digits,ds)-1;
if ((d >= b1) OR (d < 0)) then msgbox("Invalid digit: " + ds); j:=-1; break; end;
CAS("tmp(2):=tmp(2)+d*b1^k");
k:=k-1;
end;
if (j == -1) then continue; end;
//tmp[2] contains a decimal number in the form of a fraction now.
n:="";
//conversion of tmp[1] to base b2 and storing it into n
t:=size(ipn);
if t then
k:=CAS("ip(ln(tmp(1))/ln(b2))"); //calculation of maximal power of b2
//which is less or equal to tmp[1]
for j from k downto 0 do
d:=CAS("ip(tmp(1)/(b2^j))");
ds:=mid(digits,d+1,1);
n:=n+ds;
CAS("tmp(1):=tmp(1)-d*b2^j");
end;
end;
//conversion of tmp[2] to base b2 and storing it into n
t:=size(fpn);
if t then
n:=n+".";
for j from 1 to maxdigits do
d:=CAS("ip(tmp(2)*b2)");
CAS("tmp(2):=tmp(2)*b2-d");
// floating point issue
if CAS("tmp(2)<0") then
CAS("tmp(2):=tmp(2)+1");
d:=d-1;
end;
ds:=mid(digits,d+1,1);
n:=n+ds;
if CAS("tmp(2)==0") then break; end;
end;
end;
t:=b1;
b1:=b2;
b2:=t;
else
msgbox("Invalid input");
end;
else
run:=0; //when pressed Esc leave the loop
end;
end;
END;