:

## convert/base: converting from decimal presentation to another base

Maple
`Though Maple provides routines to express integers or floating in differentinteger 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' (whilefor 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.9788124600822068Very messy and for smaller values that would give 0 :-)And (working with the classical interface) I always wanted a multiplicationin outputs, which I find more easy to read for humans (those who do not wantthat will just omit the according step).  convert(, '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                                  3This 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  + ----                                                32One 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 10Note 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` ﻿