Code:
#pragma mode( separator(.,;) integer(h64) )
// rev 6030 update
EXPORT RoundFract(V, F)
BEGIN
RETURN ROUND(V*F,0)/F;
END;
EXPORT FareyMax(Vl, DMax)
// Round a Vl to the best fraction with denominator < DMax
BEGIN
LOCAL VlE, Tmp;
LOCAL DbN,DbD, FnN,FnD, RsN,RsD,RsE;
PRINT();
VlE:= ABS(Vl);
DbN:= IP(VlE); DbD:=1; FnN:=DbN+1; FnD:=1;
RsN:= ROUND(VlE,0); RsD:= 1; RsE:= ABS(VlE-(RsN/RsD));
PRINT(STRING(SIGN(Vl)*RsN,2,0)+"/"+STRING(RsD,2,0));
WHILE DbD+FnD <= DMax DO
Tmp:= (DbN+FnN)/(DbD+FnD);
IF RsE > ABS(VlE-Tmp) THEN RsN:= (DbN+FnN); RsD:= (DbD+FnD); RsE:= ABS(VlE-(RsN/RsD)); PRINT(STRING(SIGN(Vl)*RsN,2,0)+"/"+STRING(RsD,2,0));END;
IF Tmp < VlE THEN DbN:= (DbN+FnN); DbD:= (DbD+FnD); ELSE FnN:= (DbN+FnN); FnD:= (DbD+FnD); END;
END;
// RETURN "'"+STRING(SIGN(Vl)*RsN,2,0)+"/"+STRING(RsD,2,0)+"'";
RETURN EXPR("QUOTE("+STRING(SIGN(Vl)*RsN,2,0)+"/"+STRING(RsD,2,0)+")");
END;
EXPORT FareyDelta(Vl, Error)
// round Vl to the smallest fraction with |Vl - fraction| < Error
BEGIN
LOCAL VlE, Tmp;
LOCAL DbN,DbD, FnN,FnD, RsN,RsD,RsE;
VlE:= ABS(Vl);
DbN:= IP(VlE); DbD:=1; FnN:=DbN+1; FnD:=1;
RsN:= ROUND(VlE,0); RsD:= 1; RsE:= ABS(VlE-(RsN/RsD));
WHILE RsE > Error DO
Tmp:= (DbN+FnN)/(DbD+FnD);
IF RsE > ABS(VlE-Tmp) THEN RsN:= (DbN+FnN); RsD:= (DbD+FnD); RsE:= ABS(VlE-(RsN/RsD)); END;
IF Tmp < VlE THEN DbN:= (DbN+FnN); DbD:= (DbD+FnD); ELSE FnN:= (DbN+FnN); FnD:= (DbD+FnD); END;
END;
// RETURN "'"+STRING(SIGN(Vl)*RsN,2,0)+"/"+STRING(RsD,2,0)+"'";
RETURN EXPR("QUOTE("+STRING(SIGN(Vl)*RsN,2,0)+"/"+STRING(RsD,2,0)+")");
END;
EXPORT FareyDisp(Vl,Rnd)
// round Vl to the smallest fraction that match the display
BEGIN
LOCAL VlE, Tmp;
LOCAL DbN,DbD, FnN,FnD, RsN,RsD,RsE;
VlE:= ABS(ROUND(Vl,Rnd));
DbN:= IP(VlE); DbD:=1; FnN:=DbN+1; FnD:=1;
RsN:= ROUND(VlE,0); RsD:= 1; RsE:= ABS(VlE-ROUND(RsN/RsD,Rnd));
WHILE RsE > 0 DO
Tmp:= (DbN+FnN)/(DbD+FnD);
IF RsE > ABS(VlE-Tmp) THEN RsN:= (DbN+FnN); RsD:= (DbD+FnD); RsE:= ABS(VlE-ROUND(RsN/RsD,Rnd)); END;
IF Tmp < VlE THEN DbN:= (DbN+FnN); DbD:= (DbD+FnD); ELSE FnN:= (DbN+FnN); FnD:= (DbD+FnD); END;
END;
RETURN EXPR("QUOTE("+STRING(SIGN(Vl)*RsN,2,0)+"/"+STRING(RsD,2,0)+")");
END;
Nota: if you want FareyMax to be a simple function, just remove all PRINT commands from source code.