%mathpiper,def="Rationalize"

//Retract("Rationalize",*);

10 # Rationalize(aNumber_IsList) <-- Rationalize /@ aNumber;

20 # Rationalize( _aNumber ) <--
[
    Local(result,n,d);
    result:=Substitute(aNumber,{{x},IsNumber(x) And Not(IsInteger(x))},"RationalizeNumber");
    If(InVerboseMode(),Tell("",result));
    If(Length(VarList(aNumber))=0,
      [
        n:=Numerator(result);
        If(Type(n)="Numerator",n:=result);
        d:=Denominator(result);
        If(Type(d)="Denominator",d:=1);
        result := n*(1/d);
      ]
    );
    result;
];
%/mathpiper

   




%mathpiper_docs,name="Rationalize",categories="User Functions;Numbers (Operations)"
*CMD Rationalize --- convert floating point numbers to fractions
*STD
*CALL
	Rationalize(expr)

*PARMS

{expr} -- an expression containing real numbers

*DESC

This command converts every real number in the expression "expr"
into a rational number. This is useful when a calculation needs to be
done on floating point numbers and the algorithm is unstable.
Converting the floating point numbers to rational numbers will force
calculations to be done with infinite precision (by using rational
numbers as representations).

It does this by finding the smallest integer $n$ such that multiplying
the number with $10^n$ is an integer. Then it divides by $10^n$ again,
depending on the internal gcd calculation to reduce the resulting
division of integers.

*E.G.
    
In> Rationalize(-1.2)
Result: (-6)/5
In> Rationalize(1.3+7.43*x)
Result: 743/100*x+13/10
In> {1.2,3.123,4.5}
Result: {1.2,3.123,4.5};
In> Rationalize(%)
Result: {6/5,3123/1000,9/2};

*SEE IsRational

%/mathpiper_docs

   


