Though Maple provides routines to express integers or floating in different
integer bases the output looks not as nice as I want to have it.

And for example it does not work as expected using the 'simple ways' (while
for hex there is no simple way for floats):

  Digits:=16; # for all the following

  x:=frac(evalf(Pi)):
  x:= x* SFloat(1,-14);
                                              -14
                     x := 0.141592653589793 10

  xxx:=convert(x, octal);
  `error`[absolute, relative] = x -xxx, 1 - xxx/x;

                                               -16
                   xxx := 0.3000000000000000 10
                                                   -14
  error[absolute, relative] = 0.1385926535897930 10   , 0.9788124600822068

Very messy and for smaller values that would give 0 :-)


And (working with the classical interface) I always wanted a multiplication
in outputs, which I find more easy to read for humans (those who do not want
that will just omit the according step).

  convert([183], 'bytes'): # ASCII 183
  theDot:=parse(%); #lprint(%);

                             theDot := ·

Now (currently using Maple 12) the following seems to give me what I want,
converting a number (in base=10) into its presentation in a new base 'b'
in nice form (well, if it is not too long ... positives are enough):

  convert_base:=proc(X::And(nonnegative,{float, integer, fraction}), b::posint)
  global theDot;
  local bName, L, intPart, fracPart, k, x, oldBase, newBase, n, p,m,M;
  if b=1 then error "invalid base = %1 (must be larger than 2)", b end if;
  bName:=convert(b, name);
 
  # integer part
  L:=convert(trunc(X), base, b);
 
  intPart:= sum( 'L'[k]* bName^(k-1),k=1.. nops(L));
 
  # convert first (=left) argument in multiplications to a name,
  # then concatenate with theDot, finally multiply again
  intPart:= subsindets(intPart, '`*`',
    't -> cat(convert(op(1,t),name), theDot) * op(2,t)');
 
  # fractional part
  x:=frac(X);
  if (x=0) then return intPart end if;
  oldBase:=10;
  newBase:=b;
  n := ceil(ln(oldBase^Digits)/ln(newBase)); # new Digit length for new base
 
  p:=floor( log[b](x/b^(n-1)) );
  m:= floor( x/b^(p) );
  M:=convert(m, base, b);
 
  # here add gives the better sorting
  fracPart:=bName^p * add( M[k]*bName^(k-1),k=1.. nops(M));

  return intPart + sort(expand(fracPart));  
  end proc; #maplemint(%);

Converting such expressions back to decimal notation then is done by

  convert_decimal:=proc(x_in_some_BASE)
  global theDot;
  convert(x_in_some_BASE, string):
  StringTools:-SubstituteAll(%, theDot, ""):
  StringTools:-SubstituteAll(%, "`", ""):
  parse(%);
  end proc;


For the above example that gives a correct transform:

  convert_base(x, 8);
  convert_decimal(%);
  xx:=evalf(%);
  `error`[absolute, relative] = x -xx, 1 - xx/x;

                                               -14
                    xx := 0.1415926535897930 10

                  error[absolute, relative] = 0., 0.


Some more examples:

  x:=3;
  convert_base(x, 2);
  convert_decimal(%);
                                x := 3

                                1 + 2
                                  3

This is, because convert/name is used, so 1+2 not immediately gives 3

  x:=0.125+10.^5-1;
  convert_base(x, 32);
  convert_decimal(%);
  xx:=evalf(%);
  `error`[absolute, relative] = x -xx, 1 - xx/x;

                            x := 99999.125

                                  2        3    4
                  31 + 20· 32 + 32  + 3· 32  + ----
                                                32

One sees some multiplication sign (but only, if it is not 1*term),
the error is zero (in that precision).

  x:=frac(evalf(Pi));
  convert_base(x, 16);
  convert_decimal(%);
  xx:=evalf(%);
  `error`[absolute, relative] = x -xx, 1 - xx/x;

                                             -15        -15
           error[absolute, relative] = 0.1 10   , 0.7 10

Note that convert(x,hex) here would result in an error message.

And it works on fractions

  x:=3 + 1/2^51;
  convert_base(x, 2);
  convert_decimal(%);
  xx:=evalf(%);
  `error`[absolute, relative] = x -xx, 1 - xx/x;

                             6755399441055745
                        x := ----------------
                             2251799813685248

                                      1
                             1 + 2 + ---
                                      51
                                     2

                           6755399441055745
                           ----------------
                           2251799813685248

                       xx := 3.000000000000000
                                                    -15
              error[absolute, relative] = 0., 0.2 10


Please Wait...