из принципа "увидел прикольный алгоритм, не проходи мимо" :-)
на stackoverflow встретился компактный алг. поиск ближайшей правильной дроби - портировал в MQL.
/** поиск ближайшей подходящей дроби порт с https://stackoverflow.com/questions/5124743/algorithm-for-simplifying-decimal-to-fractions/37573546#37573546 **/ double Fraction(const double x0,unsigned long &num,unsigned long &den,double &sign,double err=1.0e-10) { sign=x0>=0?1.0:-1.0; double g=MathAbs(x0); unsigned long a=0; unsigned long b=1; unsigned long c=1; unsigned long d=0; unsigned long s; unsigned int iter=0; double diff; do { s = (unsigned long)MathFloor(g); num = a+s*c; den = b+s*d; a = c; b = d; c = num; d = den; g = 1.0/(g-s); diff=MathAbs(sign * num / den - x0); if (err>diff) { return diff; } } while(iter++<1.0e6); return double("nan"); } void Test(double v,string s="") { unsigned long num,den; double sign; double diff=Fraction(v,num,den,sign); if (MathIsValidNumber(diff)) { PrintFormat("%s = %s%lu/%lu +%12f",s==""?DoubleToString(v,12):s,sign<0?"-":"",num,den,diff); } } void OnStart() { Test(1.01); Test(1.02); Test(2.03); Test(1.33333333333); Test(0.66666666666); Test(M_PI,"pi"); Test(MathPow(M_PI,2),"pi^2"); Test(1.0/M_PI,"1/pi"); Test(1.0/MathPow(M_PI,2),"1/pi^2"); Test(M_E,"e"); Test(1.0/M_E,"1/e"); Test((MathSqrt(5)+1)/2); // golden ratio Test((MathSqrt(5)-1)/2); Test((MathSqrt(2)+1)); // silver ratio Test((MathSqrt(2)-1)); }


