%mathpiper,def="Decimal"

10 # Decimal( n_IsInteger ) <-- {n,{0}};
10 # Decimal( (n_IsPositiveInteger) / (d_IsPositiveInteger) ) <--
[
  Local(result,rev,first,period,repeat,static);
  result:={Quotient(n,d)};
  Decimal(result,Modulo(n,d),d,350);
  rev:=DecimalFindPeriod(result);
  first:=rev[1];
  period:=rev[2];
  repeat:=result[first .. (first+period-1)];
  static:=result[1 .. (first-1)];
  DestructiveAppend(static,repeat);
];
20 # Decimal(_n/_m)_((n/m)<0) <-- "-":Decimal(-n/m);

10 # Decimal(_result , _n , _d,_count ) <--
[
  While(count>0)
  [
    DestructiveAppend(result,Quotient(10*n,d));
    n:=Modulo(10*n,d);
    count--;
  ];
];

DecimalFindPeriod(_list) <--
[
  Local(period,nr,reversed,first,i);
  reversed:=Rest(DestructiveReverse(FlatCopy(Rest(list))));
  nr:=Length(reversed)>>1;
  period:=1;
  first:=reversed[1];

  For(i:=1,i<nr,i++)
  [
    If(reversed[i+1] = first And DecimalMatches(reversed,i),
      [
        period:=i;
        i:=nr;
      ]
      );
  ];

  first:=Length(list)-period;
  While(first>1 And list[first] = list[first+period]) first--;
  first++;

  {first,period};
];

DecimalMatches(_reversed,_period) <--
[
  Local(nr,matches,first);
  nr:=0;
  matches:=True;
  first:=1;
  While((nr<100) And matches)
  [
    matches := (matches And
       (reversed[first .. (first+period-1)] = reversed[(first+period) .. (first+2*period-1)]));
    first:=first+period;
    nr:=nr+period;
  ];
  matches;
];

%/mathpiper



%mathpiper_docs,name="Decimal",categories="User Functions;Numbers (Operations)"
*CMD Decimal --- decimal representation of a rational
*STD
*CALL
	Decimal(frac)

*PARMS

{frac} -- a rational number

*DESC

This function returns the infinite decimal representation of a
rational number {frac}.  It returns a list, with the first element
being the number before the decimal point and the last element the
sequence of digits that will repeat forever. All the intermediate list
elements are the initial digits before the period sets in.

*E.G.

In> Decimal(1/22)
Result: {0,0,{4,5}};
In> N(1/22,30)
Result: 0.045454545454545454545454545454;

*SEE N
%/mathpiper_docs