You could also do using Bart fractions like that:
const fracDenom = 8*9*5*7*11;
var
value: double;
frac: TFraction;
begin
value := 3.141592653589793238;
frac.Init(round(value*fracDenom),fracDenom);
frac.Normalize;
writeln(frac.ToString);
writeln(frac.Numerator/frac.Denominator);
readln;
end; That gives you Pi = 17417/5544.
However you have not much control of the number of digits here. You could use the continued fraction and Bart fractions like that:
function ContinuedFraction(AValue: Double; AMaxNumerator, AMaxDenominator: int64): TFraction;
const maxDigits = 99999999999999;
var
backup: TFraction;
depth: integer;
epsilon: double;
begin
if AMaxNumerator > maxDigits then AMaxNumerator := maxDigits;
if AMaxDenominator > maxDigits then AMaxDenominator := maxDigits;
depth := 1;
epsilon:= 1/AMaxDenominator;
backup := ContinuedFractionWithDepth(AValue, depth, epsilon);
while depth < 50 do
begin
inc(depth);
result := ContinuedFractionWithDepth(AValue, depth, epsilon);
if (abs(result.Numerator) > AMaxNumerator) or
(result.Denominator > AMaxDenominator) then
begin
result := backup;
exit;
end;
backup := result;
end;
end;
function ContinuedFractionWithDepth(AValue: Double; AMaxDepth: integer; AEpsilon: Double = 1e-15): TFraction;
var fracPart: Double;
unitFraction: TFraction;
intPart: int64;
begin
if AValue < 0 then
begin
result := ContinuedFractionWithDepth(-AValue, AMaxDepth, AEpsilon);
result.Numerator := -result.Numerator;
end
else
begin
intPart := Trunc(AValue);
result.Init(intPart,1);
if AMaxDepth > 1 then
begin
unitFraction.Init(1,1);
fracPart := AValue-intPart;
if fracPart > AEpsilon then
result += unitFraction / ContinuedFractionWithDepth(1/fracPart, AMaxDepth-1, AEpsilon);
end;
end;
end;
const maxNb = 999;
var
value: double;
frac: TFraction;
begin
value := 3.141592653589793238;
frac:= ContinuedFraction(value, maxNb,maxNb);
writeln(frac.ToString);
writeln(frac.Numerator/frac.Denominator);
readln;
end;
With maxNb = 99, this gives you Pi = 22/7
with maxNb = 999, this gives you Pi = 355/113
Note that is not optimum because 355/113 is a better approximation.