I think this will fail almost always (with big numbers):
F = test input
F1 and F2 are the result of 2 different FloatToFraction implementations.
Prec = used precision
(The lower the precision, the lower the change the test succeeds)
F = 80901531/115151512
F1 = 34073573/48498754
F2 = 23413979/33326379
F1.ToFloat = 0.702565946333384
F2.ToFloat = 0.702565946333384
Prec = 0.000000000000001
Here's the code I used to test the two impementations with random input and per input 15 iterations for different precisions:
procedure FTF_Test(Func1, Func2: TFracFunc; Name: String);
var
F1,F2: TFraction;
D1, D2, Prec, Diff1, Diff2: Double;
i, Count: Integer;
T: TextFile;
procedure OpenT;
begin
if FileExists(Name+'_Test.txt') then
Append(T)
else
Rewrite(T);
end;
begin
AssignFile(T,Name+'_Test.txt');
OpenT;
writeln(T,'Testing: ',Name);
CloseFile(T);
// Randomize;
Count := 0;
repeat
D1 := Random;
Prec := 0.1;
for i := 1 to 15 do
begin
write('.');
try
F1 := Func1(D1, Prec);
Diff1 := Abs(F1.ToFloat - D1);
F2 := Func2(D1, Prec);
Diff2 := Abs(F2.ToFloat - D1);
if (Diff1 > Prec) or (Diff2 > Prec) then
begin
Inc(Count);
OpenT;
writeln(T,'Fail: ');
writeln(T,'D = ',D1:24:24);
writeln(T,'F1.ToFloat = ',F1.ToFloat:24:24);
writeln(T,'F2.ToFloat = ',F2.ToFloat:24:24);
writeln(T,'Prec = ',Prec:24:24);
writeln(T,'Diff1 = ',Diff1:24:24);
writeln(T,'Magnitude = ',Round(Diff1/Prec));
writeln(T,'Diff2 = ',Diff2:24:24);
writeln(T,'Magnitude = ',Round(Diff2/Prec));
writeln(T,'F1 = ',F1.ToString);
writeln(T,'F2 = ',F2.ToString);
CloseFile(T);
writeln;
writeln('Fail: ');
writeln('Fail: ');
writeln('D = ',D1:24:24);
writeln('F1.ToFloat = ',F1.ToFloat:24:24);
writeln('F2.ToFloat = ',F2.ToFloat:24:24);
writeln('Prec = ',Prec:24:24);
writeln('Diff1 = ',Diff1:24:24);
writeln('Magnitude = ',Round(Diff2/Prec));
writeln('Diff2 = ',Diff2:24:24);
writeln('Magnitude = ',Round(Diff2/Prec));
writeln('F1 = ',F1.ToString);
writeln('F2 = ',F2.ToString);
end;
except
on E: Exception do
begin
Inc(Count);
OpenT;
writeln(T,'Exception: ',E.Classname,', Message: ',E.Message);
writeln(T,' D=',D1:16:16,' Prec=',Prec:16:16);
CloseFile(T);
writeln;
writeln('Exception: ',E.Classname,', Message: ',E.Message);
writeln(' D=',D1:16:16,' Prec=',Prec:16:16);
end;
end;
Prec := Prec/10;
end;
until Count >= 15;
OpenT;
writeln(T,'Stopped after ',Count,' failures.');
CloseFile(T);
writeln('Stopped after ',Count,' failures.');
end;
It shows failure in the code from "mathforum":
Fail:
D = 0.548813502304256
F1.ToFloat = 0.548813502361793
F2.ToFloat = 0.548813502302539
Prec = 0.000000000010000
Diff1 = 0.000000000057537
Magnitude = 6
Diff2 = 0.000000000001717
Magnitude = 0
F1 = 29395/53561
F2 = 172924/315087
Bart